Перейти к содержанию
Официальный форум поддержки Simpla

Экспорт товаров с выбором категорий


Рекомендуемые сообщения

  • Ответов 81
  • Дата создания
  • Последний ответ

Лучшие авторы в теме

Лучшие авторы в теме

Изображения в теме

 

Поделись)))

Есть готовое решение http://simpla-addons.org/blog/modules/2xx-eksport-tovarov-po-kategoriyam права поделиться смогу не безвозмездно.

Ссылка на сообщение
Поделиться на другие сайты

В simpla/ajax/export.php вместо

private $filename = 'export.csv';

напиши

$category_id = $this->request->get('category_id');
   if(!empty($category_id))
   {
       $category = $this->categories->get_category((int)$category_id);
   }
private $filename = $category->name.'.csv';

Это топорно (лишний запрос будет), но не критично.

 

Такое безобразие работать точно не будет, потому как нарушаются правила формирования кода класса.

Явно  советчик поленился потратить пару минут на проверку совета.

Указанный код надо вставлять В ДРУГОМ МЕСТЕ (например, в начале функции fetch), и без "private"...

Ссылка на сообщение
Поделиться на другие сайты

Такое безобразие работать точно не будет, потому как нарушаются правила формирования кода класса.

Явно  советчик поленился потратить пару минут на проверку совета.

Указанный код надо вставлять В ДРУГОМ МЕСТЕ (например, в начале функции fetch), и без "private"...

 

simpla/ajax/export.php вставляю:

public function fetch()
	{
		
$category_id = $this->request->get('category_id');
if(!empty($category_id))
{
$category = $this->categories->get_category((int)$category_id);
}
$filename = $category->name.'.csv';

...

В результате ругается, скрин прилагаю

 

UPD.     private $filename = 'export.csv'; - закоментировал выше

Изменено пользователем artbe
Ссылка на сообщение
Поделиться на другие сайты

simpla/ajax/export.php вставляю:

...

В результате ругается, скрин прилагаю

 

UPD.     private $filename = 'export.csv'; - закоментировал выше

 

нужно обращаться к $this->filename

 

также надо передавать это имя файла назад, т.к. в скрипте прописано явно и будет скачивать всегда export.csv

window.location.href = 'files/export/export.csv';

еще я бы вставил строку с переименованием файла все-таки в условие по айди

private $filename = 'export.csv';
...
$category_id = $this->request->get('category_id');
if(!empty($category_id)) {
  $category = $this->categories->get_category((int)$category_id);
  $this->filename = $category->name.'.csv';
}
...

в этом случае если айди не придет файл будет иметь дефолтное название а не пустое.

Изменено пользователем mishanya
Ссылка на сообщение
Поделиться на другие сайты

Очень правильно заметил недостатки mishanya, спасибо.

 

В конце функции fetch тогда вместо

            return array('end'=>true, 'page'=>$page, 'totalpages'=>$total_products/$this->products_count);        
вставить
             return array('end'=>$this->filename, 'page'=>$page, 'totalpages'=>$total_products/$this->products_count);        
 

И строку

window.location.href = 'files/export/export.csv';

заменить на

window.location.href = 'files/export/'+data.end;

Ссылка на сообщение
Поделиться на другие сайты

Благодарю, все работает, файл выгружается с названием категории.

Однако теперь другая ошибка, в самом .csv файле - Название категории отображается "траслитом"

 

Скрин прилагаю. + если выбрать категорию, где нет товаров - то слайдер просто виснет

 

Ссылка на сообщение
Поделиться на другие сайты

Благодарю, все работает, файл выгружается с названием категории.

Однако теперь другая ошибка, в самом .csv файле - Название категории отображается "траслитом"

 

Скрин прилагаю. + если выбрать категорию, где нет товаров - то слайдер просто виснет

 

 

это не транслит. это кодировка плывет у вас.

Ссылка на сообщение
Поделиться на другие сайты

это не транслит. это кодировка плывет у вас.

 

Подскажите пожалуйста как лечить, если вставлю после условия:

		setlocale(LC_ALL, 'ru_RU.1251');
		$this->db->query('SET NAMES cp1251');

то, происходит банальная ошибка, экспорт проходит на 103% и виснет, а самого файла нет.

 

Начало функции fetch:

	public function fetch()
	{
		if(!$this->managers->access('export'))
			return false;

		// Эксель кушает только 1251
		setlocale(LC_ALL, 'ru_RU.1251');
		$this->db->query('SET NAMES cp1251');
		
		
		$category_id = $this->request->get('category_id');
			if(!empty($category_id)) {
			  $category = $this->categories->get_category((int)$category_id);
			  $this->filename = $category->name.'.csv';
			}
		
		$category_id = $this->request->get('category_id');
		$category_children = array();
		if(!empty($category_id))
		{
			$category = $this->categories->get_category((int)$category_id);
			if (isset($category))
				$category_children = $category->children;
		}

Повторяются 2 переменные: $category_id = $this->request->get('category_id');

Ссылка на сообщение
Поделиться на другие сайты

Подскажите пожалуйста как лечить, если вставлю после условия: 

................

 

Повторяются 2 переменные: $category_id = $this->request->get('category_id');

 

вообще я бы рекомендовал открывать csv файлы в openoffice и тогда не будет проблем с кодировками и не нужно будет ставить их в файл.

 

то что повторяються ничего страшного. по сути, вы можете объединить код:

		$category_id = $this->request->get('category_id');
			if(!empty($category_id)) {
			  $category = $this->categories->get_category((int)$category_id);
			  $this->filename = $category->name.'.csv';
			}
		
		$category_id = $this->request->get('category_id');
		$category_children = array();
		if(!empty($category_id))
		{
			$category = $this->categories->get_category((int)$category_id);
			if (isset($category))
				$category_children = $category->children;
		}

в один кусок

		$category_id = $this->request->get('category_id');
		$category_children = array();
		if(!empty($category_id))
		{

			$category = $this->categories->get_category((int)$category_id);
			if (isset($category)) {
				$category_children = $category->children;
                                $this->filename = $category->name.'.csv';
                        }
		}
Изменено пользователем mishanya
Ссылка на сообщение
Поделиться на другие сайты

 

вообще я бы рекомендовал открывать csv файлы в openoffice и тогда не будет проблем с кодировками и не нужно будет ставить их в файл.

 

то что повторяються ничего страшного. по сути, вы можете объединить код:

		$category_id = $this->request->get('category_id');
			if(!empty($category_id)) {
			  $category = $this->categories->get_category((int)$category_id);
			  $this->filename = $category->name.'.csv';
			}
		
		$category_id = $this->request->get('category_id');
		$category_children = array();
		if(!empty($category_id))
		{
			$category = $this->categories->get_category((int)$category_id);
			if (isset($category))
				$category_children = $category->children;
		}

в один кусок

		$category_id = $this->request->get('category_id');
		$category_children = array();
		if(!empty($category_id))
		{

			$category = $this->categories->get_category((int)$category_id);
			if (isset($category)) {
				$category_children = $category->children;
                                $this->filename = $category->name.'.csv';
                        }
		}

 

Как раз и открываю с openofica. Дико извеняюсь, но такой при таком способе - экспорт виснет. Грузит и останавливает на 333% и все на этом. Не могли, ли бы глянуть на файл export.php, полный листинг привожу:

<?php

require_once('../../api/Simpla.php');

class ExportAjax extends Simpla
{	
	private $columns_names = array(
			'category'=>         'Категория',
			'name'=>             'Товар',
			'price'=>            'Цена',
			'currency'=>         'Валюта',
			'url'=>              'Адрес',
			'visible'=>          'Видим',
			'featured'=>         'Рекомендуемый',
			'brand'=>            'Бренд',
			'variant'=>          'Вариант',
			'compare_price'=>    'Старая цена',
			'sku'=>              'Артикул',
			'stock'=>            'Склад',
			'meta_title'=>       'Заголовок страницы',
			'meta_keywords'=>    'Ключевые слова',
			'meta_description'=> 'Описание страницы',
			'annotation'=>       'Аннотация',
			'body'=>             'Описание',
			'images'=>           'Изображения'
			);
			
	private $column_delimiter = ';';
	private $subcategory_delimiter = '/';
	private $products_count = 10;
	private $export_files_dir = '../files/export/';
	private $filename = 'export.csv';
	

	public function fetch()
	{
		if(!$this->managers->access('export'))
			return false;
		
		$category_id = $this->request->get('category_id');
		if(!empty($category_id)) {
		  $category = $this->categories->get_category((int)$category_id);
		  $this->filename = $category->name.'.csv';
		}

		// Эксель кушает только 1251
		setlocale(LC_ALL, 'ru_RU.1251');
		$this->db->query('SET NAMES cp1251');
		
	$category_id = $this->request->get('category_id');
		$category_children = array();
		if(!empty($category_id))
		{

			$category = $this->categories->get_category((int)$category_id);
			if (isset($category)) {
				$category_children = $category->children;
                                $this->filename = $category->name.'.csv';
                        }
		}
	
		// Страница, которую экспортируем
		$page = $this->request->get('page');
		if(empty($page) || $page==1)
		{
			$page = 1;
			// Если начали сначала - удалим старый файл экспорта
			if(is_writable($this->export_files_dir.$this->filename))
				unlink($this->export_files_dir.$this->filename);
		}
		
		// Открываем файл экспорта на добавление
		$f = fopen($this->export_files_dir.$this->filename, 'ab');
		
		// Добавим в список колонок свойства товаров
		$features = $this->features->get_features();
		foreach($features as $feature)
			$this->columns_names[$feature->name] = $feature->name;
		
		// Если начали сначала - добавим в первую строку названия колонок
		if($page == 1)
		{
			fputcsv($f, $this->columns_names, $this->column_delimiter);
		}
		
		// Все товары
		$products = array();
 		//foreach($this->products->get_products(array('page'=>$page, 'limit'=>$this->products_count)) as $p)
		foreach($this->products->get_products(array('page'=>$page, 'category_id'=>$category_children, 'limit'=>$this->products_count)) as $p)	
 		{
 			$products[$p->id] = (array)$p;
 			
	 		// Свойства товаров
	 		$options = $this->features->get_product_options($p->id);
	 		foreach($options as $option)
	 		{
	 			if(!isset($products[$option->product_id][$option->name]))
					$products[$option->product_id][$option->name] = str_replace(',', '.', trim($option->value));
	 		}

 			
 		}
 		
 		if(empty($products))
 			return false;
 		
 		// Категории товаров
 		foreach($products as $p_id=>&$product)
 		{
	 		$categories = array();
	 		$cats = $this->categories->get_product_categories($p_id);
	 		foreach($cats as $category)
	 		{
	 			$path = array();
	 			$cat = $this->categories->get_category((int)$category->category_id);
	 			if(!empty($cat))
 				{
	 				// Вычисляем составляющие категории
	 				foreach($cat->path as $p)
	 					$path[] = str_replace($this->subcategory_delimiter, '\\'.$this->subcategory_delimiter, $p->name);
	 				// Добавляем категорию к товару 
	 				$categories[] = implode('/', $path);
 				}
	 		}
	 		$product['category'] = implode(', ', $categories);
 		}
 		
 		// Изображения товаров
 		$images = $this->products->get_images(array('product_id'=>array_keys($products)));
 		foreach($images as $image)
 		{
 			// Добавляем изображения к товару чезер запятую
 			if(empty($products[$image->product_id]['images']))
 				$products[$image->product_id]['images'] = $image->filename;
 			else
 				$products[$image->product_id]['images'] .= ', '.$image->filename;
 		}
 
 		$variants = $this->variants->get_variants(array('product_id'=>array_keys($products)));

		foreach($variants as $variant)
 		{		
			if(isset($products[$variant->product_id]))
				{
					$v                    = array();
					$v['variant']         = $variant->name;
					$v['price']           = $variant->price;
					$v['currency'] 		  = $variant->currency;
						
					if ($variant->base_price)
						$v['price']           = $variant->base_price;
					else
						$v['price']           = $variant->price;
						
					if ($variant->base_price)
						$v['base_compare_price']           = $variant->base_compare_price;
					else
						$v['compare_price']   = $variant->compare_price;
						
					$v['sku']             = $variant->sku;
					$v['stock']           = $variant->stock;
					if($variant->infinity)
						$v['stock']           = '';
					$products[$variant->product_id]['variants'][] = $v;
				}
		}
		
		foreach($products as &$product)
 		{
 			$variants = $product['variants'];
 			unset($product['variants']);
 			
 			if(isset($variants))
 			foreach($variants as $variant)
 			{
 				$result = array();
 				$result =  $product;
 				foreach($variant as $name=>$value)
 					$result[$name]=$value;

	 			foreach($this->columns_names as $internal_name=>$column_name)
	 			{
	 				if(isset($result[$internal_name]))
		 				$res[$internal_name] = $result[$internal_name];
	 				else
		 				$res[$internal_name] = '';
	 			}
	 			fputcsv($f, $res, $this->column_delimiter);

	 		}
		}
		
		$total_products = $this->products->count_products(array('category_id'=>$category_children));
		
		if($this->products_count*$page < $total_products)
			return array('end'=>false, 'page'=>$page, 'category_id'=>$category_children, 'totalpages'=>$total_products/$this->products_count);
		else
			//return array('end'=>true, 'page'=>$page, 'category_id'=>$category_children, 'totalpages'=>$total_products/$this->products_count);
			return array('end'=>$this->filename, 'page'=>$page, 'category_id'=>$category_children, 'totalpages'=>$total_products/$this->products_count);

		fclose($f);

	}
	
}

$export_ajax = new ExportAjax();
$data = $export_ajax->fetch();
if($data)
{
	header("Content-type: application/json; charset=utf-8");
	header("Cache-Control: must-revalidate");
	header("Pragma: no-cache");
	header("Expires: -1");
	$json = json_encode($data);
	print $json;
}

Сделано, все как сказали

Изменено пользователем artbe
Ссылка на сообщение
Поделиться на другие сайты

а как можно отсортировать? нужно отсортировать так как в админке Каталога, тоесть сначала идут все товары с "категории 1/подкатегории 1" и после того как вывелись все товары с этой подкатегории выводились товары с "категории 1/подкатегории 2"?

Ссылка на сообщение
Поделиться на другие сайты

В api/Categories.php замени

	public function get_product_categories($product_id)
	{
		$query = $this->db->placehold("SELECT product_id, category_id, position FROM __products_categories WHERE product_id in(?@) ORDER BY position", (array)$product_id);
		$this->db->query($query);
		return $this->db->results();
	}	

на

	public function get_product_categories($product_id)
	{
		$query = $this->db->placehold("SELECT product_id, category_id, position FROM __products_categories WHERE product_id in(?@) ORDER BY name", (array)$product_id);
		$this->db->query($query);
		return $this->db->results();
	}	

или просто замени в запросе position на name.

Но это повлияет не только на экспорт, а и на вывод на сайте. Чтобы было только в экспорте, то нужно эту функцию переносить в файл экспорта и обращаться к ней через $this.

Изменено пользователем koteyka
Ссылка на сообщение
Поделиться на другие сайты

В api/Categories.php замени

	public function get_product_categories($product_id)
	{
		$query = $this->db->placehold("SELECT product_id, category_id, position FROM __products_categories WHERE product_id in(?@) ORDER BY position", (array)$product_id);
		$this->db->query($query);
		return $this->db->results();
	}	

на

	public function get_product_categories($product_id)
	{
		$query = $this->db->placehold("SELECT product_id, category_id, position FROM __products_categories WHERE product_id in(?@) ORDER BY name", (array)$product_id);
		$this->db->query($query);
		return $this->db->results();
	}	

или просто замени в запросе position на name.

Но это повлияет не только на экспорт, а и на вывод на сайте. Чтобы было только в экспорте, то нужно эту функцию переносить в файл экспорта и обращаться к ней через $this.

 

Очень сильный совет. Интересно, советчик его сам тестировал?  Потому как невооруженным глазом видно, что даст ошибку (в __products_categories нет поля name)...

 

Вопрос не так прост, как может показаться, и решается совсем не в одну строку...

Ссылка на сообщение
Поделиться на другие сайты

в __products_categories нет поля name

:)  Точно же. На вскидку скопипастил, а не подумал, что выборка же не из __categories идет. Мм-да-а, действительно в пару строк не сделать.

Изменено пользователем koteyka
Ссылка на сообщение
Поделиться на другие сайты
  • 2 месяца спустя...

хорошая и очень полезная доработка, но нехватает одного - выбора нескольких категорий! Кто может помочь дапилить этот функционал? конечно же не бесплатно...

Ссылка на сообщение
Поделиться на другие сайты

хорошая и очень полезная доработка, но нехватает одного - выбора нескольких категорий!

http://simpla-tuning.com/vyborochnyj-eksport-tovarov
Ссылка на сообщение
Поделиться на другие сайты

Вы правильно поняли. Мне такое слабо.

Если вдруг Вам (или кому-то еще) не слабо, то не стесняйтесь, покажите мастер-класс. Страждущие будут ох как рады и благодарны...

Ссылка на сообщение
Поделиться на другие сайты

А почему бы не сделать возможность мультивыбора у селекта и передавать этот массив?

Это же совсем не сложно.

Ссылка на сообщение
Поделиться на другие сайты

Kors спасибо за предложение конечно, модуль отличный но в моём случае нужна доработка небольшая уже существующего, а не покупка модуля ибо это разная ценовая категория, даи я хотел бы чтобы это было доступно всем ибо на самом деле очень полезная штука, а купив ваш модуль и выложив его на всеобщее обозрение будет не совсем коректно к Вам..

 

Да и я лично расматриваю модуль как временное решение, у  меня больше 100 000! товаров и 2500 категорий с подкатегориями! После 50 000 начался цирк со всей системой в целом, это просто бред :-)) - плохо работает импорт экспорт, пришьлось разбивать карту сайта, свойства в админке не привязываются к категориям, пришьлось делать привязку свойств при создании категории, начал глючить сайт при подборам по параметрам по всем категориям сразу и прочее. Но это я уже отошёл от темы. Так вот и даже если я буду выгружать и загружать по 30 000 (что симпла делает более менее нормально, ибо по опыту скажу бывает такое что чтото не выгрузит или недогрузит:-) ) то это ещё тот гемор! Поэтому сейчас ищу альтернативный метод импорта экспорта, а пока работаю с dbForge.

 

Поэтому 5 баксов за доработку отдать не жалко, попробую конечно сделать как Косяк советует, может по аналогии как свойства в админке сделаны :-)

Ссылка на сообщение
Поделиться на другие сайты

1. у меня больше 100 000! товаров и 2500 категорий с подкатегориями!

2. Поэтому 5 баксов за доработку отдать не жалко

 

Такого соотношения мне еще не встречалось...

 

3. пришьлось разбивать карту сайта,

4. пришьлось делать привязку свойств при создании категории,

 

Если Вы такое сумели сделать, тогда должны бы и свою задачу легко разрешить...

Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...

×
×
  • Создать...