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

Групповое добавление дополнительных категорий к товарам


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

Данная доработка позволяет производить групповое добавление (или удаление) дополнительных категорий к выбранным товарам, с помощью селекта внизу страницы товаров.

7a2e06078f864b25a41b0a3c48dcec85.png

 

 

 

1. В файле /simpla/design/html/products.tpl после строк:

{if $categories|count>1}
<option value="move_to_category">Переместить в категорию</option>
{/if}

Добавить:

{if $categories|count>1}
<option value="move_to_additional">Дополнительные категории</option>
{/if}

 

 

 

2. В том же файле, после строк:

<span id="move_to_category">
<select name="target_category">
    {function name=category_select level=0}
    {foreach $categories as $category}
        <option value='{$category->id}'>{section sp $level}    {/section}{$category->name|escape}</option>
        {category_select categories=$category->subcategories selected_id=$selected_id level=$level+1}
    {/foreach}
    {/function}
    {category_select categories=$categories}
</select>
</span>

Добавить:

<span id="move_to_additional">
<select name="target_additional">
    <option value="0">Удалить все доп. категории</option>
    {function name=additional_select level=0}
    {foreach $categories as $category}
        <option value='{$category->id}'>{section sp $level}    {/section}{$category->name|escape}</option>
        {additional_select categories=$category->subcategories selected_id=$selected_id level=$level+1}
    {/foreach}
    {/function}
    {additional_select categories=$categories}
</select>
</span>

 

 

 

3. В том же файле, после строк:

    // Перенос товара в другую категорию
    $("#action select[name=action]").change(function() {
        if($(this).val() == 'move_to_category')
            $("span#move_to_category").show();
        else
            $("span#move_to_category").hide();
    });
    $("#right_menu .droppable.category").droppable({
        activeClass: "drop_active",
        hoverClass: "drop_hover",
        tolerance: "pointer",
        drop: function(event, ui){
            $(ui.helper).find('input[type="checkbox"][name*="check"]').attr('checked', true);
            $(ui.draggable).closest("form").find('select[name="action"] option[value=move_to_category]').attr("selected", "selected");    
            $(ui.draggable).closest("form").find('select[name=target_category] option[value='+$(this).attr('category_id')+']').attr("selected", "selected");
            $(ui.draggable).closest("form").submit();
            return false;            
        }
    });

Добавить:

    // Добавление товару дополнительной категории
    $("#action select[name=action]").change(function() {
        if($(this).val() == 'move_to_additional')
            $("span#move_to_additional").show();
        else
            $("span#move_to_additional").hide();
    });
    $("#right_menu .droppable.category").droppable({
        activeClass: "drop_active",
        hoverClass: "drop_hover",
        tolerance: "pointer",
        drop: function(event, ui){
            $(ui.helper).find('input[type="checkbox"][name*="check"]').attr('checked', true);
            $(ui.draggable).closest("form").find('select[name="action"] option[value=move_to_additional]').attr("selected", "selected");    
            $(ui.draggable).closest("form").find('select[name=target_additional] option[value='+$(this).attr('category_id')+']').attr("selected", "selected");
            $(ui.draggable).closest("form").submit();
            return false;            
        }
    });

 

 

 

4. В файле /simpla/design/css/style.css заменить строки:

div#action span#move_to_page, div#action span#move_to_category, div#action span#move_to_brand{
    display:none;
}

На строки:

div#action span#move_to_page, div#action span#move_to_category, div#action span#move_to_additional, div#action span#move_to_brand{
    display:none;
}

 

 

 

5. В файле /simpla/ProductsAdmin.php после строк:

case 'move_to_category':
{
    $category_id = $this->request->post('target_category', 'integer');
    $filter['page'] = 1;
    $category = $this->categories->get_category($category_id);
    $filter['category_id'] = $category->children;
         
    foreach($ids as $id)
    {
        $query = $this->db->placehold("DELETE FROM __products_categories WHERE category_id=? AND product_id=? LIMIT 1", $category_id, $id);    
        $this->db->query($query);                      
        $query = $this->db->placehold("UPDATE IGNORE __products_categories set category_id=? WHERE product_id=? ORDER BY position DESC LIMIT 1", $category_id, $id);    
        $this->db->query($query);
        if($this->db->affected_rows() == 0)
            $query = $this->db->query("INSERT IGNORE INTO __products_categories set category_id=?, product_id=?", $category_id, $id);    

    }
    break;
}

Добавить:

case 'move_to_additional':
{
    $additional_id = $this->request->post('target_additional', 'integer');
    $filter['page'] = 1;
    $category = $this->categories->get_category($additional_id);
    $filter['category_id'] = $category->children;
                 
    foreach($ids as $id)
    {
        if($additional_id == 0)
        {
            $query = $this->db->placehold("DELETE FROM __products_categories WHERE product_id=? AND position<>0", $id);    
            $this->db->query($query);
        }                  
        else
        {
            $query = $this->db->placehold("SELECT count(*) as count FROM __products_categories WHERE product_id=?", $id);
            $this->db->query($query);
            $count = $this->db->result('count');
            $query = $this->db->query("INSERT IGNORE INTO __products_categories set category_id=?, product_id=?, position=?", $additional_id, $id, $count);
        }
                         

    }
    break;
} 

 

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

Молодец что написал статью!

Как будет сохраняться порядок категорий у каждого товара?

 

Посмотрите внимательно:

$query = $this->db->placehold("SELECT count(*) as count FROM __products_categories WHERE product_id=?", $id);
$this->db->query($query);
$count = $this->db->result('count');
$query = $this->db->query("INSERT IGNORE INTO __products_categories set category_id=?, product_id=?, position=?", $additional_id, $id, $count);
Изменено пользователем parampados
Ссылка на сообщение
Поделиться на другие сайты

Посмотрите внимательно:

$query = $this->db->placehold("SELECT count(*) as count FROM __products_categories WHERE product_id=?", $id);
$this->db->query($query);
$count = $this->db->result('count');
$query = $this->db->query("INSERT IGNORE INTO __products_categories set category_id=?, product_id=?, position=?", $additional_id, $id, $count);

 

 

Если посмотреть на этот код внимательно, то легко обнаружить, что вставляемая категория далеко не всегда будет последней в списке...
Ссылка на сообщение
Поделиться на другие сайты

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

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

Вы проверяли работу предлагаемой доработки?

Будьте добры, конкретный пример того, что работает неправильно.

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

А если более развёрнуто, то:

Кейс работает для каждой отдельной связки «товар» + «категория» и в данном случае count всегда будет равен текущему количеству категорий у товара.

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

Проверьте.

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

count покажет количество, но position одной из категорий может быть больше количества этих самых категорий, и как следствие категория попадет в "середину списка" категорий товара.

тут актуальнее использовать максимальное значение position+1

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

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

 

Это правильно.

 

т.е. position добовляемой доп. категории всегда будет равен count.

 

А здесь целых две ошибки: неверно как основное утверждение, так и связка "т.е.".

 

Проверьте.

 

Для того, чтобы проверить правильность Вашего утверждения, надо проверять ВСЕ ВОЗМОЖНЫЕ варианты работы в админке. Это невозможно В ПРИНЦИПЕ.

 

А вот для того, чтобы проверить НЕправильность Вашего утверждения, достаточно всего лишь привести пример. И если не зацикливаться на Вашем коде, а помнить, что в админке есть и еще довольно много действий, то привести нужный пример будет уже проще...

 

Если настаиваете на своем очевидно неправильном тезисе, готов поспорить, например на 1000$.

Я утверждаю, что Ваш метод при штатной работе в админке в некоторых ситуациях может вставлять категорию НЕ в конец списка...

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

А я утверждаю что почти каждое Ваше решение имеет изъяны.

Хватит разводить лирику.

Либо комментируем по существу (с указанием на точное место ошибки, и методами борьбы с ними), либо не комментируем вообще.

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

Kors, весь смысл Вашего сообщения, сводится к тому, что если бы у бабушки были яйца, она была бы дедушкой.

Существует правило хорошего тона: «критикуешь – предлагай».

 

Sheeft, дело в том, что count() считает с единицы, а position объявляется с нуля.

Таким образом, в случае если доп.категории удаляются «стандартно» со страницы товара или с помощью предлагаемой мной «Удалить все доп.категории», count будет равен следующей position для конкретной связки «товар»+«категория».

Обратите внимание, что при удалении/добавлении доп.категорий со страницы товара, position связок «товар»+«категории» всегда обновляется и начинается с нуля.

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

Вы проверяли работу предлагаемой доработки?

Будьте добры, конкретный пример того, что работает неправильно.

 

Сначала маленькое отступление. Многие таблицы БД имеют поле ID первичного ключа.

При создании новых записей значения ID генерируются автоматически по порядку.

Например, если в начале работы таблица пусть и админ создает 5 объектов, то они получают ID=1,2,3,4,5.

Если потом удалить пару объектов, то ряд ID будет иметь более сложную структуру, например ID=1,4,5.

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

Тем более это прекрасно знают программисты.

 

А теперь вернемся к нашим баранам. Поле position в таблице s_products_categories, хоть и не является ключевым, но ведет себя подобным образом.

Например, если в админке на странице товара указать товару 5 категорий, то для этого товара в таблице появятся 5 записей со значениями поля position=0,1,2,3,4.

А теперь, если удалить парочку из этих 5 категорий, то в таблице останутся только 3 записи, например, со значениями поля position=0,1,4.

Теперь добавим к товару новую категорию, применив предлагаемый метод. Имеем count = 3, поэтому появится добавочная запись со значением position=3.

В итоге - новая запись в порядке категорий встала не в конце списка, а в серединке.

 

Думаю, примерно такое имели в виду, кроме меня, также и Noxter в #5 и Sheeft в #8.

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

 

Если применить предложение Sheeft-а

тут актуальнее использовать максимальное значение position+1

то это исправит описанную ошибку. Но останется другая. Думаю, будет интереснее Вам самому, если найдете ее сами...

 

Хватит разводить лирику.

Либо комментируем по существу...

 

Надеюсь, Вам понравится мой подробный комментарий по существу и с деталями...

 

А я утверждаю что почти каждое Ваше решение имеет изъяны.

 

Может, Вы окажете мне ответную любезность, и прокомментируете свое утверждение развернуто и доказательно?

Меня очень интересует методика получения подобных выводов.

Если бы меня попросили оценить процент решений с изъянами или без изъянов от какого-либо работающего фрилансера, я бы сказал, что это задача необъятная:

1. надо иметь список решений с подробностями,

2. надо каждое или хотя бы большинство тестировать,

3. Если решение платное, надо еще потратиться.

В итоге, по моим прикидкам, чтобы высказывать такое с полной уверенностью и ответственностью, надо потратить рабочего времени уйму. Возможно, месяцы. Скорее всего, даже больше, чем на создание CMS с нуля. И денег немало...

4. А за время тестирования появятся новые решения или частично исправятся ошибки в существующих - для актуальности надо опять заново тестировать...

 

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

 

А теперь вернемся к нашим баранам. Поле position в таблице s_products_categories, хоть и не является ключевым, но ведет себя подобным образом.
Например, если в админке на странице товара указать товару 5 категорий, то для этого товара в таблице появятся 5 записей со значениями поля position=0,1,2,3,4.

 

Всё верно.

 

 

А теперь, если удалить парочку из этих 5 категорий, то в таблице останутся только 3 записи, например, со значениями поля position=0,1,4.

 

Я уже писал, что если доп. категории удаляются «стандартно» через админку со страницы товара, то в таблице останутся записи со значениями поля position=0,1,2, т.к. при удалении/добавлении доп. категорий, position связок «товар»+«категории» всегда обновляется и начинается с нуля. 

 

Я абсолютно согласен, что при удалении полей из таблицы вручную, проявится описанное вами поведение, но безоглядным удалением полей из БД можно всё что угодно сломать.

Таким образом, предлагаемое мной решение будет полностью работоспособным, в случае если доп. категории добавляются/удаляются через админку (как это делает большинство пользователей).

 

 

тут актуальнее использовать максимальное значение position+1

 

Можно, но всё прекрасно работает и без этого.

 

P.S.: Ну и напоследок у меня вопрос, для чего вам нужен порядок сортировки дополнительных категорий товара? Важна главная категория с position=0, а какое значение имеет порядок дополнительных?

 

 

 

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

Таким образом, предлагаемое мной решение будет полностью работоспособным, в случае если доп. категории добавляются/удаляются через админку (как это делает большинство пользователей)

 

Видимо, я недостаточно подробно объяснил, дополняю.

Проводим следующие действия (все штатно в админке + обсуждаемая доработка):

1. В админке на странице товара укажем товару 5 категорий, тогда при сохрании для этого товара в таблице появятся 5 записей со значениями поля position=0,1,2,3,4.

2. В админке на странице КАТЕГОРИЙ удалим парочку из этих 5 категорий (удалим не дополнительные категории у товара, а удалим категории вообще). В таблице останутся только 3 записи, например, со значениями поля position=0,1,4.

3. Теперь добавим к товару новую категорию, применив предлагаемый метод. Имеем count = 3, поэтому появится добавочная запись со значением position=3.

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

 

P.S.: Ну и напоследок у меня вопрос, для чего вам нужен порядок сортировки дополнительных категорий товара? Важна главная категория с position=0, а какое значение имеет порядок дополнительных?

 

Это уже другой вопрос. Большей частью этот порядок действительно не нужен. Нужно реально только разделение на основную категорию и дополнительные.

Основная категория участвует, например, в хлебных крошках, для SEO это обычно очень важно.

Поскольку уж речь зашла об этом, отмечу, что Ваша доработка при некоторых обстоятельствах может ПОРТИТЬ соотношение - основная категории и дополнительные категории. А по смыслу - не должно такого быть. Возникает уже некоторый риск проблем для SEO. Насколько я знаю, SEO-спецы такое очень не любят - менять основную категорию без веских причин...

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

Все сделал по инструкции. Чет не удаляются все доп.категории

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

http://prntscr.com/akdb8i

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

А нет, все. Разобрался. Нужно выбрать сначала "Доп.категории в первом селекте", а потом нажать "Применить". Вопрос снят

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

Обнаружился еще такой маленький момент:

если импортировать новый товар с несколькими категориями, а потом попробовать удалить доп категории предлагаемой доработкой, то это работать не  будет. Связано это с тем, что автор считает position=0 признаком основной категории, а это не всегда верно...

 

В связи с этим предложение автору:

полезно было бы сделать удаление не СРАЗУ ВСЕХ доп категорий, а одной указанной.

Ведь поскольку сделано добавление категорий, естественно сделать и обратную операцию удаления...

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

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

 

Можете пожалуйста помочь исправить данный код, чтобы категория была последней?

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

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

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

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

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

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

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

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

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

Загрузка...
×
×
  • Создать...