Stan Ezersky

Stan Ezersky

С нами с 18 февраля 2014; Место в рейтинге пользователей: #29
Воеводский Михаил
26 ноября 2016, 09:15
4
+3
2) Это ошибка MS2 при сохранении свойств доставки. Когда-то столкнулся, но PR не подготовил, причин уже не помню. Надеюсь, Василий добавит исправление в MS2.

В файлах /core/components/minishop2/processors/mgr/settings/delivery/create.class.php и /core/components/minishop2/processors/mgr/settings/delivery/update.class.php блок
foreach ($prices as $field) {
            if ($tmp = $this->getProperty($field)) {
                $tmp = preg_replace(array('#[^0-9%\-,\.]#', '#,#'), array('', '.'), $tmp);
                if (strpos($tmp, '%') !== false) {
                    $tmp = str_replace('%', '', $tmp) . '%';
                }
                if (strpos($tmp, '-') !== false) {
                    $tmp = str_replace('-', '', $tmp) * -1;
                }
                if (empty($tmp)) {
                    $tmp = 0;
                }
                $this->setProperty($field, $tmp);
            }
        }
необходимо заменить на следующий:
foreach ($prices as $field) {
            if ($tmp = $this->getProperty($field)) {
                $isPercent = false;
                $tmp = preg_replace(array('#[^0-9%\-,\.]#', '#,#'), array('', '.'), $tmp);
                if (strpos($tmp, '%') !== false) {
                    $tmp = str_replace('%', '', $tmp) . '%';
                    $isPercent = true;
                }
                if (strpos($tmp, '-') !== false) {
                    $tmp = str_replace('-', '', $tmp) * -1;
                    if ($isPercent) {
                        $tmp .= '%';
                    }
                }
                if (empty($tmp)) {
                    $tmp = 0;
                }
                $this->setProperty($field, $tmp);
            }
        }
После этого минусовой процент начнет правильно сохраняться, а обработка такого значения в остальных местах происходит корректно.
Володя
14 ноября 2016, 23:10
4
+3
так я не предлагаю вам делать выборки по 5 ресурсов. Подберите то кол-во который ваш хостинг нормально обработает, например по 5000 шт. Указываете в роботс главный файл который выглядит примерно так

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>http://site.ru/sitemap1</loc>
</sitemap>
<sitemap>
<loc>http://site.ru/sitemap2</loc>
</sitemap>
<sitemap>
<loc>http://site.ru/sitemap3</loc>
</sitemap>
</sitemapindex>
в каждом из них вызов pdoSitemap.
вроде ничего сложного?
Володя
05 августа 2016, 22:35
21
+5
можно добавить так
создать плагин на pdoToolsOnFenomInit, в нем добавить модификатор detector
<?php
switch ($modx->event->name) {
    case 'pdoToolsOnFenomInit':
    if (!$fenom = $modx->getOption('fenom', $scriptProperties)) {
        return;
    }
    if (!$MobileDetect = $modx->getService('mobiledetect', 'MobileDetect', MODX_CORE_PATH . 'components/mobiledetect/')) {
	    return;
    }
    
    $key = $MobileDetect->config['force_browser_variable'];
    $device = !empty($_GET) && array_key_exists($key, $_GET)
		? $modx->stripTags($_GET[$key])
		: '';
	if (empty($device)) {
	    $device = $MobileDetect->getSettings();
    }
    if (empty($device)) {
        $detector = $MobileDetect->getDetector();
        $device = ($detector->isMobile() ? ($detector->isTablet() ? 'tablet' : 'mobile') : 'standard');
        $MobileDetect->saveSettings($device);
    }

    $fenom->addModifier("detector", function ($value) use ($device) {
        return $value == $device;
    });

    break;
}

и теперь в любом месте можно делать так
{if 'mobile'|detector}
mobile
{/if}

{if 'tablet'|detector}
tablet
{/if}

{if 'standard'|detector}
standard
{/if}
Николай Загумённов
28 мая 2016, 22:56
7
+2
Я использовал компонент tvSuperSelect.
Чтобы с фронта добавлять тэги добавил плагин, который заполняет ТВ поле и таблицу компонента значениями:
<?php
// tvssTagsSave
$tvss = $modx->getService('tvsuperselect', 'tvsuperselect', $modx->getOption('core_path').'components/tvsuperselect/model/tvsuperselect/');
if (!($tvss instanceof tvSuperSelect)) {
    return '';
}

switch ($modx->event->name) {

    case 'OnDocFormSave':
        if (is_object($resource) && is_array($resource->_fields)) {
            $data = $resource->_fields;
            $resource_id = $data['id'];
            // $modx->log(1, print_r($data, 1));

            $flds = $tv_values = array();
            foreach ($data as $key => $value) {
                if ($key == 'tags')  {
                    $tv_id = 1;

                    $array = array_diff($value, array(''));
                    if (!empty($array)) {
                        $flds[] = array(
                            'resource_id' => $resource_id,
                            'tv_id' => $tv_id,
                            'data' => $array,
                        );

                        $tv_values[$tv_id] = $modx->toJSON($array);
                    }
                }
            }
             // пишем в таблицу пакета
            if (!empty($flds)) {
                // $modx->log(1, print_r($flds, 1));

                $table = $modx->getTableName('tvssOption');

                foreach ($flds as $fld) {
                    $sql = 'DELETE FROM '.$table.' WHERE `resource_id` = '.$fld['resource_id'].' AND `tv_id` = '.$fld['tv_id'];
                    $stmt = $modx->prepare($sql);
                    $stmt->execute();
                    $stmt->closeCursor();

                    $values = array();
                    foreach ($fld['data'] as $value) {
                        if (!empty($value)) {
                            $values[] = '('.$fld['resource_id'].',"'.$fld['tv_id'].'","'.addslashes($value).'")';
                        }
                    }

                    if (!empty($values)) {
                        $sql = 'INSERT INTO '.$table.' (`resource_id`,`tv_id`,`value`) VALUES '.implode(',', $values);
                        $stmt = $modx->prepare($sql);
                        $stmt->execute();
                        $stmt->closeCursor();
                    }
                }
            }

            // пишем в таблицу modTemplateVarResource
            if (!empty($tv_values)) {
                //$modx->log(1, print_r($tv_values, 1));

                foreach ($tv_values as $tv_id => $values) {
                    if (!$tv_obj = $modx->getObject('modTemplateVarResource', array(
                        'tmplvarid' => $tv_id,
                        'contentid' => $resource_id,
                    ))) {
                        $tv_obj = $modx->newObject('modTemplateVarResource');
                    }

                    $tv_obj->fromArray(array(
                        'tmplvarid' => $tv_id,
                        'contentid' => $resource_id,
                        'value' => $values,
                    ));
                    $tv_obj->save();
                    // $modx->log(1, print_r($tv_obj->toArray(), 1));

                    unset($tv_obj);
                }
            }
        }
    break;
}
Чтобы выводить во фронте поле добавил сниппет:
<?php
// tvssTagsOptions
/* @var pdoFetch $pdoFetch */
$fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true);
$path = $modx->getOption('pdotools_class_path', null, MODX_CORE_PATH.'components/pdotools/model/', true);
if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) {
    $pdoFetch = new $pdoClass($modx, $scriptProperties);
} else {
    return false;
}
$pdoFetch->addTime('pdoTools loaded');

if (!$modx->addPackage('tvsuperselect', MODX_CORE_PATH.'components/tvsuperselect/model/')) {
    return false;
}

$tv			= $modx->getOption('tv', $scriptProperties, ''); // TV name or...
$tvid		= $modx->getOption('tvId', $scriptProperties, ''); // ... TV id
$tvInput	= $modx->getOption('tvInput', $scriptProperties, ''); // TV input name
$res		= $modx->getOption('res', $scriptProperties, 0); // Resource id
$tpl		= $modx->getOption('tpl', $scriptProperties, 'tpl.tvssTagsOptions');

$tv_where = $tv ? array( 'name' => $tv ) : '';
$tv_where = $tv_where ?: ( $tvid? array( 'id' => $tvid ) : '' );
// print_r($tv_where);

if( empty($tv_where) ) { return; }


if( $tv_obj = $modx->getObject('modTemplateVar', $tv_where) )
{
	$value = '';
	if( $res != 0 && $tv_val_obj = $modx->getObject('modTemplateVarResource', array(
			'tmplvarid'	=> $tv_obj->id,
			'contentid'	=> $res,
	))) {
		$value = $tv_val_obj->value;
	}
	$value_arr = $modx->fromJSON($value); // Массив со значениями тэгов конкретного ресурса

	// Массив, который мы передадим в процессор, там его ловить в $scriptProperties
	$processorProps = array(
	    'tv_id' => $tv_obj->id,
	);
	// Массив опций для метода runProcessor
	$otherProps = array(
	    // Здесь указываем где лежат наши процессоры
	    'processors_path' => $modx->getOption('core_path') . 'components/tvsuperselect/processors/'
	);
	// Запускаем
	$response = $modx->runProcessor('mgr/option/getoptions', $processorProps, $otherProps);
	// И возвращаем ответ от процессора

	$options_array = $modx->fromJSON($response->response); // Массив со всеми тэгами

	
	
	if (is_array($options_array['results']) || is_object($options_array['results'])) {
		foreach($options_array['results'] as $v) {
			$selected = '';
			if (is_array($value_arr) || is_object($value_arr)) {
				foreach ($value_arr as $key => $val) {
					if ($v['value'] == $val) {
						$selected = "selected=\"selected\"";
					}
				}
			}
			$options .= "<option ". $selected ." value=\"". $v['value'] ."\">";
			$options .= $v['value'];
			$options .= "</option>";
			$selected = "";
		}
	}
	
	$return = $modx->getChunk($tpl, array(
		'tv_id'			=> $tv_obj->id,
		'tv_name'		=> $tv_obj->name,
		'tv_input_name'	=> $tvInput ?: $tv_obj->name,
		'tv_value'		=> $value,
		'res_id'		=> $res,
		'options'		=> $options
	));
	
	return $return;
}
else {
	return;
}
Чанк tpl.tvssTagsOptions:
<select name="tags[]" multiple="multiple" class="js-tvSuperSelect-tags form-control" id="ticket-tags">
	[[+options]]
</select>
В чанке с формой добавления/редактирования тикетов добавил:
<link href="/js/select2-4.0.2/dist/css/select2.min.css" rel="stylesheet" />
	<script src="/js/select2-4.0.2/dist/js/select2.min.js"></script>
	<script type="text/javascript">
		$(document).ready(function(){
			$(".js-tvSuperSelect-tags").select2({
				tags: true
			});
		});
	</script>
	<div class="form-group">
		<label for="ticket-sections">Тэги</label>
		[[!tvssTagsOptions? &tv=`tags` &res=`0`]]
		// В чанке редактирования [[!tvssTagsOptions? &tv=`tags` &res=`[[+id]]`]]
		<span class="error"></span>
	</div>
Прикрутил к полю тэгов Select2, чтобы тэги было удобно заполнять и все.
Может кому пригодится =)
Максим Кузнецов
21 мая 2016, 00:14
3
+4
Можно решить стандартным jevix'ом примерно так:

<?php
	if ($modx->event->name == 'OnDocFormSave') {
		$template = $resource->get('template');
		
		if ($template != 0) {
			$id = $resource->get('id');

			//В наборе параметров отключены неугодные теги аля script, iframe и прочие
			$jevixParams = $modx->getObject('modPropertySet',array('name'=>'Ticket'));
			$jevixOptions = $jevixParams->getProperties();

			//content
			if (strlen($content = $resource->getContent()) > 0) {
				$jevixOptions['input'] = $content;
				$content = $modx->runSnippet('jevix', $jevixOptions);
				$resource->setContent($content);
				
			}
			
			switch ($template) {
				//Шаблон с доп. тв, которое нужно обработать
				case 7:
					if (strlen($custom_tv = $resource->getTVValue('custom_tv')) > 0) {
						$jevixOptions['input'] = $custom_tv;
						$custom_tv = $modx->runSnippet('jevix', $jevixOptions);
						
						$resource->setTVValue('custom_tv', $custom_tv);
					}
					
				break;
				
			}
		}
	
		
		$resource->save();
	}
Андрей
25 апреля 2016, 16:20
2
0
Сергей, решил проблему «в лоб». Так как окно несет чисто информационный характер и никакого сложного функционала не выполняет, то было решено передать нужные параметры через data- атрибуты.
Подписываем к кнопке «В корзину»:
data-pname="[[+pagetitle:stripString=`"`]]" data-pimg="[[+thumb]]" data-pprice="[[+price]]"
А снизу такой скрипт и разметка.
Стили на свой вкус.
<script>
$(document).on('click','button.btn-submit',function(e){
	var pid = $(this).data('pid') || 0;
	var pname = $(this).data('pname');
	var pimg = $(this).data('pimg');
	var pprice = $(this).data('pprice');
	$('#pname').empty();
	$('#pprice').empty();
	$('#modal_img').empty();
	$('#pname').prepend(pname);
	$('#pprice').prepend(pprice);
	$('#modal_img').prepend('<img src="'+pimg+'" id="modal-img" width="100"/>')
	$('.modal_cart').fadeIn("normal");
});
</script>
<div class="modal_cart" style="display: none;">
    <div class="modal_content">
        <div class="closebox"><a href="#" class="close-btn deletemodal"></a></div>
        <h3><i class="fa fa-check"></i> Товар добавлен в корзину</h3>
        <div class="modal_info">
        	<div id="modal_img"></div>
            <strong id="pname"></strong>
            <div class="mod_price">Цена: <span class="price" id="pprice"></span> <i class="fa fa-rub"></i></div>
            <div class="clearfix"></div>
        <div class="buttons_modals">
            <a class="button_stay" href="javascript:;" onclick="jQuery('.modal_cart').hide()">Продолжить покупки</a>
            <a class="btn btn-default" href="/cart.html" style="padding: 15px 20px;">Оформить заказ</a>
        </div>
        </div>
    </div>
</div>
Знаю, что костылями пахнет)))
Кто поможет все упростить и сделать по фен-шую, буду благодарен))
Игорь Терентьев
28 марта 2016, 13:01
1
0
Совершенно случайно нашел на тестовом сайте минишопа… Вот как надо оказывается:
[[!pdoPage?
	&parents=`2`
	&element=`msProducts`
	&hideContainers=`1`
	&limit=`12`
	&pageLimit=`12`
	&ajaxMode=`default`
	&resources=`[[!mSearch2:default=`99999`?returnIds=`1`&limit=`0`]]`
	&sortby=`ids`
]]
Сергей Лим
11 января 2016, 04:35
1
0
Вот вроде готовый вариант. Подскажите как вытаскивать [[+price]] и тд не со страницы товара? То есть перехват этих данных по нажатию на «Добавить в корзину»

miniShop2.Callbacks.Cart.add.response.success = function() {
        $('.modal_cart').fadeIn("normal");
}
<div class="modal_cart">
    <div class="modal_content">
        <div class="closebox"><a href="#" class="close-btn deletemodal"></a></div>
        <h3>Товар добавлен в корзину</h3>
        <div class="modal_info">
            <img src="[[+thumb]]" alt="[[+pagetitle]]"/>
            <strong>[[*pagetitle]]</strong>
            <div class="mod_price">Цена: <span class="price">[[+price]]</span> <i class="rub">Р</i></div>
            <div class="clearfix"></div>
            <a class="button_stay" href="javascript:;" onclick="jQuery('.modal_cart').hide()">Продолжить покупки</a>
            <a class="button_buy" href="/cart.html">Оформить заказ</a>
        </div>
    </div>
</div>
Fi1osof
08 декабря 2015, 20:13
1
+2
Не за что!

Для пакета использовалась давняя заготовка: github.com/MODX-Club/MODX_SamplePackage
Еще есть видеоурок по нему www.youtube.com/watch?v=etZlcKVKOS4
Видео старое и немного не актуальное (так как заготовка была переработана Сергеем Прохоровым), но лучше, чем ничего.
Мордынский Николай
07 декабря 2015, 22:35
2
+1
В минишопе можно на лету цены менять bezumkin.ru/sections/components/1857/

Надо только определиться как цена меняеться либо это коэффициент какойто на который в зависимости от города меняються все цены (тогда для города можно хранить только коэффициент) либо на каждый товар для города держать свою цену

case 'msOnGetProductPrice':
		// Плагин принимает:
		// $product - объект msProductData
		// $data - массив со свойствами товара, может отсутствовать
		// $price - текущая цена товара

		// Подключаем массив значений по ссылке - так удобнее
		$values = & $modx->event->returnedValues;

		// Цена может меняться несколькими плагинами сразу, поэтому проверяем:
		if (isset($values['price'])) {
			$price = $values['price'];
		}

		// Удваиваем цену:
		$values['price'] = $price * 2;