gluck Posted May 28, 2013 Share Posted May 28, 2013 (edited) При увеличении количества товаров в магазине примерно до трех тысяч штатный способ указания аксессуаров стал потихоньку умирать. Выражается это в том, что при редактировании товара ранее назначенные аксессуары к нему выглядят так, как будто они удалены из магазина: Я предположил, что это связано с тем, что при открытии страницы редактирования товара, из базы подгружаются ВСЕ товары в магазине. Которые вы потом и видите в списке аксессуаров: ...и в какой-то момент скрипту то ли не хватает времени, чтобы увидеть их все, то ли ваш канал сглючил, то ли разрабы встроили очередную какашку... итого — в чем причина этого бага, я догадаться ниасилил, буду багодарен за подсказку Конечно можно упереться и починить штатную функцию, но тогда останется открытым другой вопрос: а когда в магазине станет 10 тысяч товаров, вы каждому будете назначать аксессуары вручную? И даже штатного Импорта какой-то момент перестанет хватать... что тогда? Мне его уже не хватает Поэтому я решил в качестве временной меры написать полностью автоматическую функцию добавления аксессуаров, а после развить ее в полуавтомат с возможностью указать какие-то принципы поиска расово верных аксессуаров. А штатную не трогать, пусть доживает сколько сможет. 1. Определимся с критериями, которым должна удовлетворять новая функция. старые, вручную назначенные аксессуары должны сохраняться до последнего весь процесс должен происходить в замкнутом цикле на стороне сервера и стабильность вашего канала не должна на него влиять уже на первом этапе должна быть возможность ограничения выбора аксессуаров из определенной категории магазина. Чтобы не получилось так, что аксессуаром для чехла предлагается телефон Edited May 28, 2013 by gluck (see edit history) Link to comment Share on other sites More sharing options...
gluck Posted May 28, 2013 Author Share Posted May 28, 2013 (edited) 2. Дополним массив $product "рандомными" аксессуарами Код написан для Prestashop 1.2.5 и будет работать в любой версии с такими же таблицами в БД и похожим принципом формирования итоговой страницы. В 1.5 не будет работать точно. В файле /product.php найдем место, где формируется массив $product, который затем передается шаблону %themedir%product.tpl. Для 1.2.5 это место здесь: $smarty->assign(array( 'cover' => $cover, 'imgWidth' => intval($size['width']), 'mediumSize' => Image::getSize('medium'), 'accessories' => $product->getAccessories(intval($cookie->id_lang)))); Заменим последнюю строку на 'accessories' => $accessories)); и приступим к формированию нашего массива $accessories. Перед строкой $smarty->assign(array( вставим код: //назначаем недостающие аксессуары рандомно $accessories = $product->getAccessories(intval($cookie->id_lang)); if ($accessories===false) $acc_count = 0; else $acc_count = count($accessories); $qty = (12 - $acc_count); $accessories_rand = $product->getAccessoriesRandom(intval($cookie->id_lang), abs($qty)); if ($accessories_rand != false) { if ($acc_count != 0) { $accessories = array_merge($accessories, $accessories_rand); } else $accessories = $accessories_rand; } else $accessories = $accessories; Число 12 в переменной $qty означает максимальное количество аксессуаров, которое впишется в ваш макет по дизайну. Именно до этого количества новая функция будет добивать аксессуары, если назначенных вручную было меньше. Если "ручных" аксессуаров будет больше чем $qty, то "рандомных" аксессуаров не прибавится, а "ручных" останется столько же, сколько и было. Вы можете изменить число 12 в любую сторону, прочитав ниже описание новой функции getAccessoriesRandom. Edited May 28, 2013 by gluck (see edit history) Link to comment Share on other sites More sharing options...
gluck Posted May 28, 2013 Author Share Posted May 28, 2013 3. Приступим к главному В файл /classes/Product.php в любое удобное вам место вставим код /** * получает аксессуары рандомно * * @param integer $id_lang Language id * @param integer $qty количество возвращаемых товаров * @return array Product accessories */ public function getAccessoriesRandom($id_lang, $qty) { global $link, $cookie; $result = Db::getInstance()->ExecuteS(' SELECT p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, i.`id_image`, il.`legend`, t.`rate`, m.`name` as manufacturer_name, cl.`name` AS category_default FROM `'._DB_PREFIX_.'accessory` LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = `id_product_2` LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.intval($id_lang).') LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.intval($id_lang).') LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1) LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.intval($id_lang).') LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (p.`id_manufacturer`= m.`id_manufacturer`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON t.`id_tax` = p.`id_tax` WHERE RAND()<0.02 AND p.`active` = 1 ORDER BY RAND() LIMIT 0, '.intval($qty).''); if (!$result) return false; return $this->getProductsProperties($id_lang, $result); } Эта функция: получает id языка и количество "рандомных" аксессуаров на добивку выбирает случайным образом это количество товаров из базы следит, чтобы эти товары были "активны" НЕ следит за их остатком на складе НЕ следит за возможными повторениями аксессуаров выдает их обратно вам в том же формате, что и штатная функция getAccessories Если вы хотите, чтобы аксессуары брались только из определенных категорий магазина, приведите код к такому виду: WHERE RAND()<0.02 AND p.`id_category_default` [список ваших категорий] AND p.`active` = 1 и собственно, вставьте ваше условие в любом удобном вам виде. Соответственно, если вы хотите, чтобы в качестве аксессуаров выдавались только товары "в наличии на складе", добавьте соответсвующие поле и условие. Некоторое внимание нужно уделить строке WHERE RAND()<0.02 В MySQL функция ORDER BY RAND() реализована слегка через задницу и заставляет базу сперва выдать ВСЕ товары и лишь только потом выбрать из них случайные. Строка WHERE RAND()<0.02 спасает нас от этого, запрашивая только часть товаров. Таким образом, пусть и не особо красиво, но мы обходим проблему "жирных" запросов, повышая быстродействие в несколько раз. Если ваш дизайн позволяет иметь около 10 аксессуаров и в вашем магазине около 3000 товаров, оставьте число 0.02 без изменений, в противном случае поиграйтесь им туда-сюда-обратно. В этой версии мне не удалось обойти проблему повторения аксессуаров, которая хоть иногда, но все же вылезает. Как обычно, буду багодарен за подсказку. Было бы совсем прекрасно придумать, как превратить эту затычку в полноценный полуавтомат с возможностью указания неких критериев, по которым будут подбираться аксессуары к тому или иному товару. Link to comment Share on other sites More sharing options...
Recommended Posts