Перед всякими праздниками владельцы магазинов хотят увеличить цены (интересно, почему цены имеют свойство только увеличиваться?), причем если товаров достаточно много — дело это становится утомительное.
Все осложняется тем, что цены устанавливаются не в стандартном поле price, а в TV-переметре таким образом:
Серебряный=250||Золотой=500||Платиновый=1000
Соответствено, товары находятся в материалах MODX.
Если бы поле цены было стандартным — проблем бы не было, но тут такое… А еще может не быть каких-то свойств товара. Или их может быть больше… В общем, от двух до [скольки-нибудь].
В общем, нужна возможность выбора категорий товаров, управление ценой товара в большую или меньшую сторону.
Вроде с вводной разобрались. Начнем.
Для начала создадим новый модуль: Модули — Управление модулями — Новый модуль (кнопка справа).
Название модуля: AutoPriceChanger
и код модуля:
$idPriceTV = 14; //ID TV-параметра, который указывает цену (поле tmplvarid в таблице modx_site_tmplvar_contentvalues) $ceil = 100; //Округляем до 100 рублей. Если поставить 10 - округлим до 10 рублей. $arrFolders = $modx->runSnippet ('Ditto', array ('startID'=>0, 'depth'=>3, 'where'=>'isfolder=1', 'sortBy'=>'{"id":"ASC"}', 'tpl'=>'tplCatList')); //Категории для выбора (чекбоксы) echo $modx->getChunk('catListScriptCheckbox'); echo '<h1>Автоменятор цен</h1>'; echo '<form action="" method="post">'; echo ' <label for="percent">На сколько процентов изменить цены: </label><input type="text" id="percent" name="percent" value="10"> <b>КНОПКА ВНИЗУ</b> <p>Количество процентов, на которые меняем цену. Если указать <em><b>ПОЛОЖИТЕЛЬНОЕ</b> число - <b>увеличит</b></em>. Если <em><b>ОТРИЦАТЕЛЬНОЕ</b> - <b>уменьшит</b></em>.</p> <p>Число становится ЦЕЛЫМ. Если введена абракадабра - берется ближайшее целое, иначе НОЛЬ.</p>'; echo ' <hr />'; echo '<p><input id="one" type="checkbox" name="one" value="all" onclick="checkAll(this)" /><label for="one">Отметить все / Снять отметку со всех</label></p>'; echo $arrFolders; echo ' <input type="submit">'; echo '</form>'; $percent = empty($_POST['percent']) ? $percent=0 : $percent=(int)$_POST['percent']; //Количество процентов, на которые меняем цену. Если указать ПОЛОЖИТЕЛЬНОЕ число - увеличит. Если ОТРИЦАТЕЛЬНОЕ - уменьшит. unset($_POST['percent']); $arrCatId = $_POST; //категории с товарами, которые надо менять if (!empty($arrCatId)) { // Собираем цену и ID из указанных категорий foreach ($arrCatId as $catId) { $result = $modx->db->query(' SELECT t1.id, t2.value FROM '.$modx->db->config['table_prefix'].'site_content AS t1, '.$modx->db->config['table_prefix'].'site_tmplvar_contentvalues AS t2 WHERE t1.id = t2.contentid AND tmplvarid='.$idPriceTV.' AND parent='.$catId.';'); while( $row = $modx->db->getRow( $result ) ) { $arrProductIds[] = $row;//['id']; } } //print_r($arrProductIds); ksort($arrProductIds); // Изменяем цены foreach ($arrProductIds as $arrPrice) { $productId = $arrPrice['id']; $strTv = $arrPrice['value']; //Разбиваем TV в массив $arrTvOne = explode('||', $strTv); foreach ($arrTvOne as $arrTvSub) { if (is_array($arrTvSub)) { $arrTv = explode('==', $arrTvSub); foreach ($arrTv as $tvValue) { //И сразу меняем цену на $percent if ( preg_match('/\d/', $tvValue) && ($tvValue != '0' || $tvValue != '00' )) { $arrTv[1] = $tvValue + $tvValue/100 * $percent; $arrTv[1] = ceil($arrTv[1]/$ceil) * $ceil; } } //Собираем обратно строку со значением TV $strTv = implode("==", $arrTv); } else { $strTv = $arrTvSub + $arrTvSub/100 * $percent; $strTv = ceil($strTv/$ceil) * $ceil; } $arrIdTvs[$productId][] = $arrTv; $arrTvSTR[] .= $strTv; } $strIdTv = implode("||", $arrTvSTR); unset($arrTvSTR); $arrNewPrice[$productId] = $strIdTv; } //print_r($arrNewPrice); // Записываем новые цены в базу foreach ($arrNewPrice as $id => $tv) { $result = $modx->db->query("UPDATE ".$modx->db->config['table_prefix']."site_tmplvar_contentvalues SET value = '".$tv."' WHERE contentid = '".$id."' AND tmplvarid = '".$idPriceTV."';"); //echo $result."\n"; } }
В принципе, я там достаточно подробно откомментировал все, но для танкистов немного разжую:
$idPriceTV — это ID параметра TV, в котором сидит цена в формате Серебряный=250||Золотой=500||Платиновый=1000
$ceil — это множитель для округления цены
$arrFolders = $modx->runSnippet (‘Ditto’, array (‘startID’=>0, ‘depth’=>3, ‘where’=>’isfolder=1’, ‘sortBy’=>'{«id»:»ASC»}’, ‘tpl’=>’tplCatList’)); — тут все должно быть понятно — просто вызываем Ditto
Теперь создадим два чанка
Чанк tplCatList (создает список чекбоксов категорий)
<input name="cat[+id+]" value="[+id+]" id="[+id+]" title="[+pagetitle+]" type="checkbox"/><label for="[+id+]">[+pagetitle+]</label><br />
Чанк catListScriptCheckbox (скрипт для чекбокса «выбрать все»)
<script type="text/javascript"> function checkAll(obj) { 'use strict'; // Получаем NodeList дочерних элементов input формы: var items = obj.form.getElementsByTagName("input"), len, i; // Здесь, увы цикл по элементам формы: for (i = 0, len = items.length; i < len; i += 1) { // Если текущий элемент является чекбоксом... if (items.item(i).type && items.item(i).type === "checkbox") { // Дальше логика простая: если checkbox "Выбрать всё" - отмечен if (obj.checked) { // Отмечаем все чекбоксы... items.item(i).checked = true; } else { // Иначе снимаем отметки со всех чекбоксов: items.item(i).checked = false; } } } } </script>
Классная штука… была бы, если бы не
« MODX Parse Error »
MODX encountered the following error while attempting to parse the requested resource:
« Execution of a query to the database failed — You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near » at line 6 »
SQL > SELECT t1.id, t2.value FROM modx_site_content AS t1, modx_site_tmplvar_contentvalues AS t2 WHERE t1.id = t2.contentid AND tmplvarid=14 AND parent=all;