'csv', ], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'file' => Yii::t('product', 'File'), ]; } public function getType() { if (!$this->type) { $this->type = 'products'; } return $this->type; } public function goPrices($from = 0, $limit = null) { set_time_limit(0); $new_products = $linked_products = 0; if (!( $handle = $this->getProductsFile('uploadFilePrices') )) { $this->errors[] = 'File not found'; return false; } if (file_exists(Yii::getAlias('@uploadDir/goPrices.lock'))) { return 'Task already executed'; } $ff = fopen(Yii::getAlias('@uploadDir/goPrices.lock'), 'w+'); fclose($ff); $filesize = filesize(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFilePrices')); if ($from) { fseek($handle, $from); } $j = 0; $is_utf = ( preg_match( '//u', file_get_contents( Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFilePrices'), null, null, null, 1000000 ) ) ); if ($from == 0) { ProductStock::updateAll([ 'quantity' => 0 ]); ProductVariant::updateAll([ 'status' => 1 ], 'status != 2'); } while (empty( $limit ) || $j++ < $limit) { if (!( ( $data = fgetcsv($handle, 10000, ";") ) !== false )) { break; } foreach ($data as &$value) { if (!$is_utf) { $value = iconv('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value); } $value = trim($value); } // данные строк $modification_code = @$data[ 0 ]; $price = floatval(@$data[ 1 ]); $price_promo = floatval(@$data[ 2 ]); $count = intval(@$data[ 3 ]); $city_name = @$data[ 4 ]; $product_title = @$data[ 5 ]; if (empty ( $modification_code )) { continue; } // товары в пути // if (empty ($city_name)) // { // $this->saveNotFoundRecord ( // [$modification_code, $product_title], // Yii::getAlias('@uploadFilePricesAway') // ); // // $this->output[] = 'Товар '. $product_title . ' в пути'; // // continue; // } if (( $productVariant = ProductVariant::find() ->filterWhere([ 'sku' => $modification_code ]) ->one() ) === null ) { // 'Нет даной модификации в базе'; // $this->saveNotFoundRecord ( // [$modification_code, $product_title], // Yii::getAlias('@uploadFilePricesNoVariant') // ); $this->output[] = 'Для товара ' . $product_title . ' не найдено соотвествие'; continue; } // ===== Set stock ==== if (!$city_name) { if (!$count) { if ($productVariant->status !== 2) { $productVariant->status = 0; } if ($price_promo) { $productVariant->price_old = $price; $productVariant->price = $price_promo; } else { $productVariant->price = $price; $productVariant->price_old = $price_promo; } $productVariant->save(false, ['status', 'price', 'price_promo']); continue; } $city_name = 'Склад'; } if (( $stock = Stock::find() ->filterWhere([ 'name' => trim($city_name) ]) ->one() ) === null ) { // Create stock $stock = new Stock(); $stock->name = trim($city_name); $stock->save(); } $productStock = ProductStock::find() ->where( [ 'product_variant_id' => $productVariant->product_variant_id, 'stock_id' => $stock->stock_id, ] ) ->one(); if (!$productStock instanceof ProductStock) { $productStock = new ProductStock; $productStock->product_variant_id = $productVariant->product_variant_id; $productStock->stock_id = $stock->stock_id; $productStock->product_id = $productVariant->product_id; } $productStock->quantity = $count; $productStock->save(); $productStocks = ProductStock::find() ->where([ 'product_variant_id' => $productVariant->product_variant_id ]) ->andWhere( [ '<>', 'stock_id', $stock->stock_id, ] ) ->all(); $quantity = array_sum(ArrayHelper::getColumn($productStocks, 'quantity')) + $count; if ($price_promo) { $productVariant->price_old = $price; $productVariant->price = $price_promo; } else { $productVariant->price = $price; $productVariant->price_old = $price_promo; } $productVariant->stock = $quantity; if ($productVariant->status !== 2) { $productVariant->status = 0; } $productVariant->save(); $this->output[] = 'Товар ' . $product_title . ' успешно сохранен'; } $result = [ 'end' => feof($handle), 'from' => ftell($handle), 'totalsize' => $filesize, 'items' => $this->output, ]; fclose($handle); if ($result[ 'end' ]) { unlink(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFilePrices')); } unlink(Yii::getAlias('@uploadDir/goPrices.lock')); return $result; } public function goProducts($from = 0, $limit = null) { set_time_limit(0); $new_products = $linked_products = 0; if (!( $handle = $this->getProductsFile('uploadFileProducts') )) { $this->errors[] = 'File not found'; return false; } if (file_exists(Yii::getAlias('@uploadDir/goProducts.lock'))) { return 'Task already executed'; } $ff = fopen(Yii::getAlias('@uploadDir/goProducts.lock'), 'w+'); fclose($ff); $filesize = filesize(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFileProducts')); if ($from) { fseek($handle, $from); } $j = 0; $is_utf = ( preg_match( '//u', file_get_contents( Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFileProducts'), null, null, null, 1000000 ) ) ); $result_items = []; while (empty( $limit ) || $j++ < $limit) { if (!( ( $data = fgetcsv($handle, 10000, ";") ) !== false )) { break; } foreach ($data as &$value) { if (!$is_utf) { $value = iconv('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value); } $value = trim($value); } // будет всегда 19 элементов for ($i = 0; $i <= 18; $i++) { if (!isset ( $data[ $i ] )) { $data[ $i ] = null; } } // 1 Группа (категория) $catalog_names = explode(',', $data[ 0 ]); if (empty ( $catalog_names )) { $result_items[] = "Не указана категория (строка $j) "; continue; } // 2 Бренд $brand_name = $data[ 1 ]; if (empty ( $brand_name )) { $result_items[] = "Не указан бренд (строка $j)"; continue; } // 3 Название товара $product_name = $data[ 2 ]; if (empty ( $product_name )) { $result_items[] = "Не указано наименование товара (строка $j)"; continue; } if (preg_match('/^.+\(#(\d+)#\)$/', trim($product_name), $remote_id)) { if (!empty( $remote_id[ 1 ] )) { $remote_id = $remote_id[ 1 ]; $product_name = substr($product_name, 0, strpos($product_name, '(#' . $remote_id . '#)')); } } // 4 Описание Укр $product_body_uk = $data[ 3 ]; // 5 Описание Рус $product_body_ru = $data[ 4 ]; // 6 Фильтр [god:2013-2014]*[pol:мужской]*[naznacenie-germo-beg:Для вещей]*[material-germo-bag:нет]*[value-germo-bag:нет]*[weight-germo-bag:нет]*[ipx-germo-bag:нет]*[in-pacage-bag:нет]*[size-germo-bag:нет]*[rekomend-germo-bag:нет] $filters = explode('*', $data[ 5 ]); // 11 Цена акция $product_cost_old = floatval($data[ 7 ]); $product_cost = ''; // 10 Цена if ($product_cost_old) { $product_cost_old = floatval($data[ 6 ]); $product_cost = floatval($data[ 7 ]); } // 12 Акция $product_akciya = (bool) $data[ 8 ]; // 13 Сопуд. Тов. $similar = explode(',', $data[ 9 ]); // 14 Новинки $product_new = (bool) $data[ 10 ]; // 15 Топ продаж $product_top = (bool) $data[ 11 ]; // 17 ВИДЕО КОД $product_video = $data[ 12 ]; // 18 Галлерея фото if (trim($data[ 13 ])) { $fotos = explode(',', trim($data[ 13 ])); } // 19 Штрих код товара. // расшифровал - это модификации товара! $product_image = explode('=', $data[ 14 ]); $product_image = @$product_image[ 3 ]; if (!empty( $remote_id )) { if (( $_product = Product::find() ->filterWhere([ 'product_id' => $remote_id ]) ->one() ) === null ) { $_product = new Product(); } } elseif (( $_product = Product::find() ->filterWhere([ 'name' => trim($product_name) ]) ->one() ) === null ) { $_product = new Product(); } $is_new_product = empty( $_product->product_id ); $category_id = []; foreach ($catalog_names as $catalog_name) { // ==== Set category ==== if (( $category = Category::find() ->filterWhere([ 'name' => trim($catalog_name) ]) ->one() ) === null ) { // Create category $category = new Category(); $category->name = trim($catalog_name); $category->save(); } $category_id[] = $category->category_id; } $_product->categories = $category_id; // ===== Set brand ==== if ($brand_name) { if (( $brand = Brand::find() ->filterWhere([ 'name' => trim($brand_name) ]) ->one() ) !== null ) { $_product->brand_id = $brand->brand_id; } else { // Create brand $brand = new Brand(); $brand->name = trim($brand_name); $brand->save(); $_product->brand_id = $brand->brand_id; } } $_product->name = $product_name; $_product->video = $product_video; $_product->description = $product_body_ru; $_product->is_top = $product_top; $_product->akciya = $product_akciya; $_product->is_new = $product_new; if (!$_product->save()) { $result_items[] = 'Product #' . $_product->name . ' not saved' . " (строка $j)"; continue; } if (!empty( $fotos )) { foreach ($fotos as $foto) { $source_image = Yii::getAlias('@uploadDir') . '/product_images/' . urlencode($foto); if (file_exists($source_image)) { if (( $productImage = ProductImage::find() ->andFilterWhere([ 'image' => $foto ]) ->andFilterWhere( [ 'product_id' => $_product->product_id ] ) ->one() ) === null ) { copy($source_image, Yii::getAlias('@productsDir') . "/" . $foto); $productImage = new ProductImage(); $productImage->product_id = $_product->product_id; $productImage->image = $foto; $productImage->save(); } } } } // нужно для проставления характеристик относящихся к модификациям $MOD_ARRAY = []; for ($i = 14; $i < count($data); $i++) { if (!empty ( $data[ $i ] )) { $mod_arr = explode('=', $data[ $i ]); $mod_art = $mod_arr[ 0 ]; $variant_filters = explode('*', $mod_arr[ 1 ]); $mod_color = $mod_arr[ 2 ]; $mod_image = $mod_arr[ 3 ]; $mod_stock = isset( $mod_arr[ 4 ] ) ? $mod_arr[ 4 ] : 1; $mod_cost = isset( $product_cost ) ? floatval($product_cost) : 0; $mod_old_cost = floatval($product_cost_old); // Check product variant if (( $_productVariant = ProductVariant::find() ->andFilterWhere([ 'sku' => $mod_art ]) ->andFilterWhere( [ 'product_id' => $_product->product_id ] ) ->one() ) === null ) { $_productVariant = new ProductVariant(); $_productVariant->product_id = $_product->product_id; } $_productVariant->product_unit_id = 1; $_productVariant->sku = $mod_art; $_productVariant->price = $mod_cost; $_productVariant->price_old = $mod_old_cost; $_productVariant->stock = $mod_stock; $product_variant_type_name = ''; if (!empty ( $mod_color )) { $product_variant_type_name = 'Цвет'; $_productVariant->name = $mod_color; } if (!empty ( $variant_filters )) { $variants_options = $this->saveFilters($variant_filters, 1, $category_id); } if (isset( $variants_options ) && !empty( $variants_options )) { $_productVariant->options = $variants_options; } // ===== Set variant type ==== if ($product_variant_type_name) { if (( $product_variant_type = ProductVariantType::find() ->filterWhere( [ 'name' => $product_variant_type_name ] ) ->one() ) !== null ) { $_productVariant->product_variant_type_id = $product_variant_type->product_variant_type_id; } else { $product_variant_type = new ProductVariantType(); $product_variant_type->name = $product_variant_type_name; $product_variant_type->save(); $_productVariant->product_variant_type_id = $product_variant_type->product_variant_type_id; } } $_productVariant->save(); $MOD_ARRAY[] = $_productVariant->product_variant_id; if ($mod_image) { $source_image = Yii::getAlias('@productsDir') . '/' . urlencode($mod_image); if (file_exists($source_image)) { if (( $variantImage = ProductImage::find() ->andFilterWhere([ 'image' => $mod_image ]) ->andFilterWhere( [ 'product_variant_id' => $_productVariant->product_variant_id ] ) ->one() ) === null ) { // copy($source_image, Yii::getAlias('@productsDir') . "/" . $mod_image); $variantImage = new ProductImage(); $variantImage->product_id = $_product->product_id; $variantImage->product_variant_id = $_productVariant->product_variant_id; $variantImage->image = $mod_image; $variantImage->save(); } } } } } if (!empty ( $filters )) { $options = $this->saveFilters($filters, 0, $category_id); } if (isset( $options ) && !empty( $options )) { $_product->options = $options; } $_product->save(); $result_items[] = "Product {$_product->name} #{$_product->product_id} saved (" . ( $is_new_product ? 'new product' : 'exists product' ) . ")" . " (строка $j)"; } $result = [ 'end' => feof($handle), 'from' => ftell($handle), 'totalsize' => $filesize, 'items' => $result_items, ]; fclose($handle); if ($result[ 'end' ]) { unlink(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFileProducts')); } unlink(Yii::getAlias('@uploadDir/goProducts.lock')); return $result; } private function getProductsFile($file_type) { $filename = Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@' . $file_type); if (!is_file($filename)) { $this->errors[] = "File $filename not found"; return false; } return fopen($filename, 'r'); } private function saveNotFoundRecord(array $line, $filename) { $str = implode(';', $line) . "\n"; $str = iconv("UTF-8//TRANSLIT//IGNORE", "windows-1251", $str); $fg = fopen(Yii::getAlias('@uploadDir') . '/' . $filename, 'a+'); fputs($fg, $str); fclose($fg); } /** * @param $filters array of filters like [['pol'='мужской'],['god' = '2013'],['volume'='25 * л']*['size'='49 x 30 x 20см'],['composition'='600D полиэстер']] * @param $level 0 for products and 1 for product variant * @param $catalog_names array catalogs id * * @return array */ private function saveFilters($filters, $level, $catalog_names) { $options = []; foreach ($filters as $filter) { preg_match_all('/\[(.*):(.*)\]/', $filter, $filter); if (empty( $filter[ 1 ][ 0 ] )) { continue; } $filter_name = trim($filter[ 1 ][ 0 ]); $taxGroup = TaxGroup::find() ->where([ 'alias' => $filter_name ]) ->one(); if (!$taxGroup instanceof TaxGroup) { $taxGroup = new TaxGroup(); $taxGroup->alias = $filter_name; $taxGroup->level = $level; $taxGroup->name = $filter_name; $taxGroup->module = 'string'; $taxGroup->hierarchical = false; $taxGroup->categories = $catalog_names; $taxGroup->is_filter = false; $taxGroup->save(); } $filters_options = explode(',', $filter[ 2 ][ 0 ]); foreach ($filters_options as $filter_options) { // $parsed_filter = $this->parseFilter($filter_options); $value = null; // if ($parsed_filter !== false) { $value = TaxValueString::find() ->innerJoinWith('taxOption') // ->andWhere([ 'tax_option.alias' => $parsed_filter[ 2 ] ]) ->andWhere([ 'value' => $filter_options ]) ->andWhere([ 'tax_option.tax_group_id' => $taxGroup->tax_group_id ]) ->one(); // } if (!$value instanceof TaxValueString) { // Create option $option = new TaxOption(); $option->tax_group_id = $taxGroup->tax_group_id; // if($parsed_filter !== false) { // $option->name = $parsed_filter[1]; // $option->alias = $parsed_filter[2]; // } else { $option->name = $filter_options; // } $option->save(); $value = new TaxValueString(); $value->tax_option_id = $option->tax_option_id; $value->value = $filter_options; $value->save(); $option->default_value = $value->tax_value_id; $option->save(); } $options[] = $value->tax_option_id; } } return $options; } // private function parseFilter($filter) // { // $regex = '/^(.+)\(#(.+)#\)$/'; // if (preg_match($regex, $filter, $result)) { // return $result; // } else { // return false; // } // } }