/** * Imports an actual product record in to the database. * * @param array Array of record data */ protected function _ImportRecord($record) { if(empty($record['prodname'])) { $this->ImportSession['Results']['Failures'][] = implode(",", $record['original_record'])." ".GetLang('ImportProductsMissingName'); return; } if ($message = strtokenize($_REQUEST, '#')) { $this->ImportSession['Results']['Failures'][] = implode(",", $record['original_record'])." ".GetLang(B('UmVhY2hlZFByb2R1Y3RMaW1pdA==')); return; } $record = $this->normalizeInventoryTracking($record); $productHash = uniqid('IMPORT', true); $productId = 0; $hasThumb = false; $productFiles = array(); $productImages = array(); $existing = null; $isOverrideDuplicates = !empty($this->ImportSession['OverrideDuplicates']); $dupeCheckWhere = ''; // Is there an existing product with this product ID ? if (!empty($record['productid'])) { $query = "SELECT * FROM [|PREFIX|]products WHERE productid = " . (int)$record['productid']; $result = $GLOBALS["ISC_CLASS_DB"]->Query($query); if($existing = $GLOBALS["ISC_CLASS_DB"]->Fetch($result)) { // Overriding existing products, set the product id if($isOverrideDuplicates) { $productId = $existing['productid']; $this->addImportResult('Updates', $record['prodname']); } else { // a product was found, but we're not updating existing record: skip $this->addImportResult('Duplicates', $record['prodname']); return; } // merge existing product details with the incoming record $record = $this->mergeExistingRecord($record, $existing); } else { // no product for this id was found, skip $this->addImportResult('Failures', $record['productid'] . " " . GetLang('ImportProductNotFound')); return; } $dupeCheckWhere = " AND productid != " . (int)$record['productid']; } // Check if there is a different product with the same name $query = "SELECT * FROM [|PREFIX|]products WHERE prodname = '" . $GLOBALS['ISC_CLASS_DB']->Quote($record['prodname']) . "'" . $dupeCheckWhere; $result = $GLOBALS["ISC_CLASS_DB"]->Query($query); $differentProductWithSameName = $GLOBALS['ISC_CLASS_DB']->Fetch($result); if($differentProductWithSameName) { if($existing || !$isOverrideDuplicates) { $this->addImportResult('Duplicates', $record['prodname']); return; } $existing = $differentProductWithSameName; $productId = $existing['productid']; $this->addImportResult('Updates', $record['prodname']); $record = $this->mergeExistingRecord($record, $existing); } // Apply any default data $defaults = array( 'prodprice' => 0, 'prodcostprice' => 0, 'prodretailprice' => 0, 'prodsaleprice' => 0, 'prodweight' => 0, 'prodheight' => 0, 'prodwidth' => 0, 'proddepth' => 0, 'prodsearchkeywords' => '', 'prodsortorder' => 0, 'prodvisible' => 1, 'prodfeatured' => 0, 'prodrelatedproducts' => '-1', 'prodoptionsrequired' => 0, 'prodfreeshipping' => 0, 'prodlayoutfile' => '', 'prodtags' => '', 'prodcondition' => 'New', 'prodshowcondition' => 0, 'prodallowpurchases' => 1, 'prodeventdaterequired' => 0, 'prodeventdatefieldname' => '', 'prodeventdatelimited' => 0, 'prodeventdatelimitedtype' => 0, 'prodeventdatelimitedstartdate' => 0, 'prodeventdatelimitedenddate' => 0, 'prodbrandid' => 0, 'tax_class_name' => '', 'upc' => '', 'category' => null, ); $record += $defaults; // check validity of price columns $priceFields = array( 'prodprice', 'prodcostprice', 'prodsaleprice', 'prodretailprice' ); foreach ($priceFields as $field) { // price was invalid if (!IsPrice($record[$field])) { if ($productId) { // using existing price $record[$field] = $existing[$field]; } else { $record[$field] = 0; } $this->addImportResult('Warnings', $record['prodname']." ".GetLang('ImportProductInvalidPrice')); } } // Do we have a product file? $productFiles = array(); if (!$this->ImportSession['IsBulkEdit']) { if (!empty($record['prodfile'])) { $productFile = $this->_ImportFile($record); if ($productFile) { $productFiles[] = $productFile; } } } else { // bulk import files for ($x = 1; $x <= $this->ImportSession['MultiFieldCount']['files']; $x++) { if (empty($record['prodfile' . $x])) { continue; } $productFile = $this->_ImportFile($record, $x); if ($productFile) { $productFiles[] = $productFile; } } } // Do we have an image? $productImages = array(); if (!$this->ImportSession['IsBulkEdit']) { if(!empty($record['prodimagefile'])) { $importedImage = $this->_ImportImage($productId, $record); if ($importedImage) { $productImages[] = $importedImage; } } } else { // bulk import images for ($x = 1; $x <= $this->ImportSession['MultiFieldCount']['images']; $x++) { if (empty($record['prodimagefile' . $x])) { if (empty($record['prodimageid' . $x])) { continue; } // image file is empty but an ID was supplied, we should delete the image if ($productId) { try { $image = new ISC_PRODUCT_IMAGE($record['prodimageid' . $x]); // ensure this image is associated with this product if ($image->getProductId() == $productId) { $image->delete(); } } catch (Exception $ex) { } } continue; } $importedImage = $this->_ImportImage($productId, $record, $x); if ($importedImage) { $productImages[] = $importedImage; } } } // a category is not required if we have an existing record and ignore blanks is enabled $requireCatsField = !(!empty($record['productid']) && $this->ignoreBlankFields()); $cats = $this->getImportRecordCategories($record); if($requireCatsField && empty($cats)) { $this->addImportResult('Failures', implode(",", $record['original_record'])." ".GetLang('ImportProductsMissingCategory')); return; } // If there's a tax class, we need to fetch it now $record['tax_class_id'] = 0; if(!empty($record['tax_class_name'])) { static $taxClassCache = array(); if(!isset($taxClassCache[$record['tax_class_name']])) { $query = " SELECT id FROM [|PREFIX|]tax_classes WHERE name='".$GLOBALS['ISC_CLASS_DB']->quote($record['tax_class_name'])."' "; $taxClassCache[$record['tax_class_name']] = $GLOBALS['ISC_CLASS_DB']->fetchOne($query); } // Still don't have a matching tax class? Must be new. if(!$taxClassCache[$record['tax_class_name']]) { $newTaxClass = array( 'name' => $record['tax_class_name'] ); $taxClassCache[$record['tax_class_name']] = $GLOBALS['ISC_CLASS_DB']->insertQuery('tax_classes', $newTaxClass); } $record['tax_class_id'] = $taxClassCache[$record['tax_class_name']]; } // check the condition is valid $validConditions = array('new', 'used', 'refurbished'); if (!isset($record['prodcondition']) || !in_array(isc_strtolower($record['prodcondition']), $validConditions)) { $record['prodcondition'] = 'New'; } // Does the brand already exist? if(isset($record['brandname']) && $record['brandname'] != '') { $query = sprintf("select brandid from [|PREFIX|]brands where brandname='%s'", $GLOBALS['ISC_CLASS_DB']->Quote($record['brandname'])); $result = $GLOBALS['ISC_CLASS_DB']->Query($query); if($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) { $brandId = $row['brandid']; } // Create new brand else { // do we have permission to create brands? if ($GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Add_Brands)) { $newBrand = array( "brandname" => $record['brandname'] ); $brandId = $GLOBALS['ISC_CLASS_DB']->InsertQuery("brands", $newBrand); } else { // no brand creation permission, abort this record $this->addImportResult('Failures', $record['prodname'] . " " . GetLang('ImportNoPermissionCreateBrand')); return; } } $record['prodbrandid'] = $brandId; } else if(!$this->ignoreBlankFields()){ $record['prodbrandid'] = 0; } if (isset($record['prodfile']) && $record['prodfile'] != '') { $productType = 2; } else if (isset($existing['prodtype']) && isId($existing['prodtype'])) { $productType = (int)$existing['prodtype']; } else { $productType = 1; } // event date $record['prodeventdaterequired'] = $this->StringToYesNoInt($record['prodeventdaterequired']); if ($record['prodeventdaterequired']) { // we must have an event name if (empty($record['prodeventdatefieldname'])) { $record['prodeventdaterequired'] = 0; $this->addImportResult('Warnings', $record['prodname'] . ' ' . GetLang('ImportNoEventDateName')); } else { $record['prodeventdatelimited'] = $this->StringToYesNoInt($record['prodeventdatelimited']); if ($record['prodeventdatelimited']) { if (!empty($record['prodeventdatelimitedstartdate'])) { $record['prodeventdatelimitedstartdate'] = (int)@ConvertDateToTime($record['prodeventdatelimitedstartdate']); } if (!empty($record['prodeventdatelimitedenddate'])) { $record['prodeventdatelimitedenddate'] = (int)@ConvertDateToTime($record['prodeventdatelimitedenddate']); } // determine what type of event date it is if ($record['prodeventdatelimitedstartdate'] > 0 && $record['prodeventdatelimitedenddate'] == 0) { $record['prodeventdatelimitedtype'] = 2; // start date } elseif ($record['prodeventdatelimitedstartdate'] == 0 && $record['prodeventdatelimitedenddate'] > 0) { $record['prodeventdatelimitedtype'] = 3; // end date } elseif ($record['prodeventdatelimitedenddate'] > $record['prodeventdatelimitedstartdate']) { $record['prodeventdatelimitedtype'] = 1; // date range } else { $record['prodeventdatelimited'] = 0; $this->addImportResults('Warnings', $record['prodname'] . ' ' . GetLang('ImportEventDateInvalid')); } } } } // Verify the inventory tracking method is valid. if($record['prodinvtrack'] == 2 && !($existing && $existing['prodvariationid'])) { $this->addImportResult('Warnings', $record['prodname'] . ' ' . GetLang('ImportProductTrackInventoryNoVariations')); $record['prodinvtrack'] = $existing['prodinvtrack']; } // This is our product $productData = array( "prodname" => $record['prodname'], "prodcode" => @$record['prodcode'], "proddesc" => @$record['proddesc'], "prodsearchkeywords" => @$record['prodsearchkeywords'], "prodtype" => $productType, "prodprice" => DefaultPriceFormat($record['prodprice']), "prodcostprice" => DefaultPriceFormat($record['prodcostprice']), "prodretailprice" => DefaultPriceFormat($record['prodretailprice']), "prodsaleprice" => DefaultPriceFormat($record['prodsaleprice']), "prodavailability" => @$record['prodavailability'], "prodsortorder" => $record['prodsortorder'], "prodvisible" => (int)$record['prodvisible'], "prodfeatured" => $record['prodfeatured'], "prodrelatedproducts" => $record['prodrelatedproducts'], "prodinvtrack" => (int)@$record['prodinvtrack'], "prodcurrentinv" => (int)@$record['prodcurrentinv'], "prodlowinv" => (int)@$record['prodlowinv'], "prodoptionsrequired" => $record['prodoptionsrequired'], "prodwarranty" => @$record['prodwarranty'], "prodheight" => DefaultDimensionFormat(@$record['prodheight']), "prodweight" => DefaultDimensionFormat(@$record['prodweight']), "prodwidth" => DefaultDimensionFormat(@$record['prodwidth']), "proddepth" => DefaultDimensionFormat(@$record['proddepth']), "prodfreeshipping" => (int)$record['prodfreeshipping'], "prodfixedshippingcost" => DefaultPriceFormat(@$record['prodfixedshippingcost']), "prodbrandid" => (int)$record['prodbrandid'], "prodcats" => $cats, "prodpagetitle" => @$record['prodpagetitle'], "prodmetakeywords" => @$record['prodmetakeywords'], "prodmetadesc" => @$record['prodmetadesc'], "prodlayoutfile" => $record['prodlayoutfile'], 'prodtags' => $record['prodtags'], 'prodmyobasset' => '', 'prodmyobincome' => '', 'prodmyobexpense' => '', 'prodpeachtreegl' => '', 'prodcondition' => $record['prodcondition'], 'prodshowcondition' => (bool)$record['prodshowcondition'], 'prodallowpurchases' => (bool)$record['prodallowpurchases'], 'prodeventdaterequired' => $record['prodeventdaterequired'], 'prodeventdatefieldname' => $record['prodeventdatefieldname'], 'prodeventdatelimited' => $record['prodeventdatelimited'], 'prodeventdatelimitedtype' => $record['prodeventdatelimitedtype'], 'prodeventdatelimitedstartdate' => $record['prodeventdatelimitedstartdate'], 'prodeventdatelimitedenddate' => $record['prodeventdatelimitedenddate'], 'tax_class_id' => $record['tax_class_id'], 'upc' => $record['upc'], 'last_import' => $this->ImportSession['StartTime'], ); /** * The variation is part of the product record, so it will have to be attached to the record if this is an * update AND the existing product already has a variation */ if (isset($existing) && is_array($existing) && isId($existing['prodvariationid'])) { $productData['prodvariationid'] = $existing['prodvariationid']; } $empty = array(); // Save it $err = ''; if (!$GLOBALS['ISC_CLASS_ADMIN_PRODUCT']->_CommitProduct($productId, $productData, $empty, $empty, $empty, $err, $empty, true)) { $this->addImportResult('Failures', $record['prodname'] . " " . GetLang('ImportDatabaseError')); return; } if($productId == 0) { $productId = $GLOBALS['NewProductId']; } // Post process images $existingImages = new ISC_PRODUCT_IMAGE_ITERATOR("SELECT * FROM `[|PREFIX|]product_images` WHERE imageprodid = " . (int)$productId); $maxSort = count($existingImages); if ($this->ImportSession['DeleteImages']) { foreach ($existingImages as $existingImage) { $existingImage->delete(false); } $maxSort = 0; } if(!empty($productImages)) { // sort the images usort($productImages, array($this, "_compare_images")); // update our images with the product id foreach ($productImages as $image) { $image->setProductId($productId); // ensure that an image doesn't have a sort set higher than max, or if no sort specified, then also set it to the highest. if ($image->getSort() > $maxSort || $image->getSort() === null) { $image->setSort($maxSort); $maxSort++; } $image->saveToDatabase(false); } } // Delete existing files if ($this->ImportSession['DeleteDownloads']) { $query = " SELECT * FROM [|PREFIX|]product_downloads WHERE productid = " . $productId; $result = $GLOBALS['ISC_CLASS_DB']->Query($query); while ($download = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) { // Remove the file from the file system @unlink(GetConfig('DownloadDirectory') . "/" . $download['downfile']); // Delete from the database $GLOBALS['ISC_CLASS_DB']->DeleteQuery('product_downloads', 'WHERE downloadid = ' . $download['downloadid']); } } // Process product files if(!empty($productFiles)) { foreach($productFiles as $file) { $file['productid'] = $productId; $GLOBALS['ISC_CLASS_DB']->InsertQuery("product_downloads", $file); } } ++$this->ImportSession['Results']['SuccessCount']; }
public function CopyProductStep2() { if($message = strtokenize($_REQUEST, '#')) { $GLOBALS['ISC_CLASS_ADMIN_ENGINE']->DoError(GetLang(B('UmVhY2hlZFByb2R1Y3RMaW1pdA==')), $message, MSG_ERROR); exit; } $prodId = (int)$_POST['originalProductId']; // Get the information from the form and add it to the database $arrData = array(); $arrCustomFields = array(); $arrVariations = array(); $err = ""; $this->_GetProductData(0, $arrData); $this->_GetCustomFieldData(0, $arrCustomFields); $this->_GetVariationData(0, $arrVariations); $this->_GetProductFieldData(0, $arrProductFields); $discount = $this->GetDiscountRulesData(0, true); $downloadError = ''; if (isset($_FILES['newdownload']) && isset($_FILES['newdownload']['tmp_name']) && $_FILES['newdownload']['tmp_name'] != '') { if (!$this->SaveProductDownload($downloadError)) { $this->CopyProductStep1($downloadError, MSG_ERROR, true, $prodId); return; } } // Does a product with the same name already exist? $query = "SELECT productid FROM [|PREFIX|]products WHERE prodname='".$GLOBALS['ISC_CLASS_DB']->Quote($arrData['prodname'])."'"; $result = $GLOBALS['ISC_CLASS_DB']->Query($query); $existingProduct = $GLOBALS['ISC_CLASS_DB']->Fetch($result); if($existingProduct['productid']) { return $this->CopyProductStep1(GetLang('ProductWithSameNameExists'), MSG_ERROR, true, $prodId); } // Validate out discount rules if (!empty($discount) && !$this->ValidateDiscountRulesData($error)) { $_POST['currentTab'] = 7; $this->CopyProductStep1($error, MSG_ERROR, true, $prodId); return; } //Validate Google Website Optimizer form if(isset($_POST['prodEnableOptimizer'])) { $optimizer = getClass('ISC_ADMIN_OPTIMIZER'); $error = $optimizer -> validateConfigForm(); if($error!='') { $_POST['currentTab'] = 8; $this->EditProductStep1($error, MSG_ERROR, true); return; } } // Commit the values to the database if ($this->_CommitProduct(0, $arrData, $arrVariations, $arrCustomFields, $discount, $err, $arrProductFields)) { // Log this action $GLOBALS['ISC_CLASS_LOG']->LogAdminAction($GLOBALS['NewProductId'], $arrData['prodname']); if ($GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Manage_Products)) { // Save the words to the product_words table for search spelling suggestions Store_SearchSuggestion::manageSuggestedWordDatabase("product", $GLOBALS['NewProductId'], $arrData['prodname']); if(isset($_POST['addanother'])) { FlashMessage(GetLang('ProductAddedSuccessfully'), MSG_SUCCESS); header("Location: index.php?ToDo=addProduct"); exit; } else { FlashMessage(GetLang('ProductAddedSuccessfully'), MSG_SUCCESS); header("Location: index.php?ToDo=viewProducts"); exit; } } else { FlashMessage(GetLang('ProductAddedSuccessfully'), MSG_SUCCESS); header("Location: index.php"); exit; } } else { if ($GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Manage_Products)) { FlashMessage(sprintf(GetLang('ErrProductNotAdded'), $err), MSG_ERROR); header("Location: index.php?ToDo=addProduct"); exit; } else { FlashMessage(sprintf(GetLang('ErrProductNotAdded'), $err), MSG_ERROR); header("Location: index.php"); exit; } } }