Кирилл Киселев

Кирилл Киселев

С нами с 12 июля 2016; Место в рейтинге пользователей: #427
Роман Ильин
12 сентября 2017, 23:09
13
+2
Сниппет для удаления старых версий:

<?php
/**
 * versionCleanX
 *
 * @author Scott Pronych, September 27, 2013
 *
 * DESCRIPTION
 *
 * For use with VersionX to delete old content
 *
 * PROPERTIES:
 *
 * &contentType - can be resource, chunk, plugin, snippet, template, or templatevar
 * &maxVersions - integer value for max number of versions you would like to keep
 *
 * USAGE:
 *
 * [[!versionCleanX? &contentType=`resource` &maxVersions=`10`]]
 *
 */
 
$cx_type = $modx->getOption('contentType', $scriptProperties, 'resource');
$cx_max = (int) $modx->getOption('maxVersions', $scriptProperties, 5);
 
$GLOBALS['count'] = 1;
$GLOBALS['total'] = 0;
$GLOBALS['deleted'] = 0;
$GLOBALS['page_total'] = 0;
$GLOBALS['page_deleted'] = 0;
$GLOBALS['page_name'] = '';
$GLOBALS['prev_content_id'] = 0;
$GLOBALS['prev_version_id'] = 0;
 
switch ($cx_type) {
    case 'chunk':
        $name = 'name';
        break;
    case 'plugin':
        $name = 'name';
        break;
    case 'snippet':
        $name = 'name';
        break;
    case 'template':
        $name = 'templatename';
        break;
    case 'templatevar':
        $name = 'name';
        break;
    default:
        $name = 'title';
        $cx_type = 'resource';
}
 
$GLOBALS['db_name'] = 'modx_versionx_' . $cx_type;
 
function delete_row ($id) {
    global $modx;
    $query = "DELETE FROM `" . $GLOBALS['db_name'] . "` WHERE version_id = '" . $id . "'";
    $result = $modx->query($query);
    if (!is_object($result)) return false;
    else {
        $GLOBALS['deleted']++;
        $GLOBALS['page_deleted']++;
        $GLOBALS['page_total']++;
        $GLOBALS['total']++;
        $GLOBALS['count']++;
        return true;
    }
}
 
function log_row () {
    $GLOBALS['data'] .= '<tr><td>' . $GLOBALS['page_name'] . '</td><td>' . $GLOBALS['page_total'] . '</td><td>' . $GLOBALS['page_deleted'] . "</td></tr>\n";
    $GLOBALS['page_deleted'] = 0;
    $GLOBALS['page_total'] = 1;
    $GLOBALS['count'] = 1;
}
 
$query = "SELECT version_id, content_id, " . $name . " AS page_title FROM `" . $GLOBALS['db_name'] . "` ORDER BY content_id ASC, version_id DESC";
 
$GLOBALS['data'] = '';
$output = 'An error occurred: ';
$versionx = $modx->query($query);
if (!is_object($versionx)) {
   return $output . 'query error ' . print_r($modx->errorInfo(), true);
}
else {
 
while($row = $versionx->fetch(PDO::FETCH_ASSOC)) {
    // New content_id so reset
    if ($prev_content_id == 0) {
        $prev_content_id = $row['content_id'];
        $prev_version_id = $row['version_id'];
        $GLOBALS['total']++;
        $GLOBALS['page_total']++;
        $GLOBALS['count']++;
        $GLOBALS['page_name'] = $row['page_title'];
    }
    elseif ($prev_content_id != $row['content_id']) {
        if ($GLOBALS['count'] > $cx_max) {
            if (!delete_row($prev_version_id)) return $output .  'deleting row for ' . $GLOBALS['page_name'] . ' Row: ' . $prev_content_id . ' ' . print_r($modx->errorInfo(), true);
            $GLOBALS['page_total']--;
 
        }
        else {
            $GLOBALS['total']++;
            $GLOBALS['count']++;
        }
        log_row();
        $prev_content_id = $row['content_id'];
        $prev_version_id = $row['version_id'];
        $GLOBALS['page_name'] = $row['page_title'];
    }
    // Content count is over the max so delete previous row
    elseif ($GLOBALS['count'] > $cx_max) {
            delete_row($prev_version_id);
            $prev_content_id = $row['content_id'];
            $prev_version_id = $row['version_id'];
    }
    else {
        $GLOBALS['count']++;
        $GLOBALS['page_total']++;
        $GLOBALS['total']++;
        $prev_content_id = $row['content_id'];
        $prev_version_id = $row['version_id'];
    }
}
log_row();
 
if ($GLOBALS['data'] != '') {
$output = '<h3>VersionX Cleanup for ' . $GLOBALS['db_name'] . '</h3>
<p>Total records: <strong>' . $GLOBALS['total'] . '</strong>
Total deleted: <strong>' . $GLOBALS['deleted'] . '</strong></p>
<table class="table table-striped">
<thead>
<tr>
<th>Page name</th>
<th>Total found</th>
<th>Deleted</th>
</tr>
</thead>
<tbody>
' . $GLOBALS['data'] .  '</tbody></table>
';
}
else $output = 'Error: no data found.';
}
 
$query = "OPTIMIZE TABLE `" . $GLOBALS['db_name'] . "`";
$versionx = $modx->query($query);
if (!is_object($versionx)) {
   $output = 'Optimize error ' . print_r($modx->errorInfo(), true) . $output;
}
 
return $output;


Вызывать так:
[[!versionCleanX? &contentType=`resource` &maxVersions=`10`]]
Володя
04 июля 2017, 16:51
4
+2
примерно так
Ext.override(miniShop2.grid.Orders , {
    getMenu: function (grid, rowIndex) {
        var ids = this._getSelectedIds();
        var row = grid.getStore().getAt(rowIndex);
        var menu = miniShop2.utils.getMenu(row.data['actions'], this, ids);
        menu.push({
          text: 'Печать'
          ,handler: function () {
                window.open('http://www.example.com?ReportID=1', '_blank');
            }
        });
        this.addContextMenuItem(menu);
    }
});
Сергей Водолагин
19 июня 2017, 18:43
8
+1
Вот друзья помогли (так как глубина от родителей до нужных ресурсов от 1 до 5 вот решение)
[[pdoResources?
    &parents=`4`
    &limit=`100`
    &sortby=`{ "pm5":"ASC","pm4":"ASC", "pm3":"ASC", "pm2":"ASC", "pm1":"ASC" }`
    &where=`{ "template": 10 }`
    &tpl=`tplSklad`
    &leftJoin=`{
        "p1": {
            "class": "modResource",
            "on": "p1.id = modResource.id"
        },
        "p2": {
            "class": "modResource",
            "on": "p2.id = p1.parent"
        },
        "p3": {
            "class": "modResource",
            "on": "p3.id = p2.parent"
        },
        "p4": {
            "class": "modResource",
            "on": "p4.id = p3.parent"
        },
        "p5": {
            "class": "modResource",
            "on": "p5.id = p4.parent"
        }
    }`
    &select=`{
        "modResource": "*",
        "p1": "COALESCE(p1.menuindex, 999999999) as pm1",
        "p2": "COALESCE(p2.menuindex, 999999999) as pm2",
        "p3": "COALESCE(p3.menuindex, 999999999) as pm3",
        "p4": "COALESCE(p4.menuindex, 999999999) as pm4",
        "p5": "COALESCE(p5.menuindex, 999999999) as pm5"
    }`
]]
mngatoff
30 марта 2017, 15:33
1
0
попробуй дописать баннеры в настройку extension_packages
Владимир Бабусенко
20 января 2017, 15:44
2
+3
Недавно была такая задача.
<?php
$prodID = $_POST['prodID']; //id продуктов
$quantity = $_POST['quantity']; //количество продукта

//MiniShop2
$miniShop2 = $modx->getService('minishop2','miniShop2', MODX_CORE_PATH . 'components/minishop2/model/minishop2/', $scriptProperties);
        if (!($miniShop2 instanceof miniShop2)) return;
        // Инициализируем класс в текущий контекст
        $miniShop2->initialize($modx->context->key, $scriptProperties);

        //Очистим корзину и заказ
        $miniShop2->cart->clean();
        $miniShop2->order->clean();
        //Новые данные заказа
        $miniShop2->order->add('delivery',1); //доставка самовывоз
        $miniShop2->order->add('payment',1); //новый-неоплаченный
        $miniShop2->order->add('email', 'email'); 
        $miniShop2->order->add('comment',$_POST['comment']); //можно комментарий добавить

// Добавляем товары в корзину, если надо
foreach ($prodID as $k => $v){
     //Добавляем товары в корзину
    $miniShop2->cart->add($v, $quantity[$k]); //(id товара, кол-во товара)
}

//Формируем заказ
$miniShop2->order->submit();
При таком все события вызываются, письма отправляются.
Константин Ильин
16 ноября 2016, 19:55
2
+2
Чтож, уже ноябрь, но лучше поздно чем никогда)

Спасибо Сергей Шлокову, он на пальцах мне обьяснил что так как я хотел сделать выше — нельзя.
Последовательность такая:
1. Нажимается кнопка.
2. В функции кнопки вызывается ajax запрос к процессору который выдает поля.
3. Только когда ajax выполнился вызывается окно. В вызов окна сразу подсовываются готовые поля, сформированные из ответа ajax.

Код функции процессора — process ()
public function process()
    {
        /*некий код*/
	$fields = '';
        // Существует какая то некая таблица в которой 1 строка это поле
        $table = $this->modx->getTableName('FieldsItems');
        $query = $this->modx->query("SELECT * FROM ".$table." WHERE active = 1");
	
        if (!is_object($query)) {
           
           return $this->failure($this->modx->lexicon('fl_data_err_get_field'));

        }else{

           $arr = $query->fetchAll(PDO::FETCH_ASSOC);

           foreach ($arr as $value) {

               $fields[] = array(
                    'xtype' => 'textarea',
                    'fieldLabel' => $value['name'],
                    'name' => "fl-".$value['code'],
                    'id' => 'ext-gen-fl-'.$value['code'],
                    'anchor' => "99%",
                    'allowBlank' => "false",
                    'value' => $fieldsValues[$value['code']] 
                );
           }

        }
        return $this->success('',$fields); // Возвращаем массив полей
    }

Как это в EXT.JS. Тут два запроса ajax, первый получает поля, второй к процессору get который выдает данные об объекте.
MODx.Ajax.request({
            url: Fl.config.connectorUrl
            ,params: {
                action: "mgr/data/get_fields", // Тот самый процессор который выдает поля
                id_res: MODx.request.id,
            }
            ,listeners: {
                success: {fn: function(res) {
                    
                    var fieldsArr = res['object']; // Ответ от процессора с полями, он возвращает массив с данными полей
                    fieldsArr = fieldsArr || {}; 
                    MODx.Ajax.request({
                        url: this.config.url,
                        params: {
                            action: 'mgr/data/get',
                            id: MODx.request.id,
                        },
                        listeners: {
                            success: {
                                fn: function ( r ) { 
                                   
                                    var w = MODx.load({
                                        xtype: 'fl-data-window-update',
                                        id: Ext.id(),
                                        addFields: fieldsArr, // Здесь передаем поля в вызов окна
                                        record: r,
                                        listeners: {
                                            success: {
                                                fn: function () {
                                                    this.refresh();
                                                }, scope: this
                                            },
                                            hide: {
                                                fn: function () {
                                                    setTimeout(function(){w.destroy();},200);
                                                }, scope: this
                                            }
                                        }
                                    });
                                    w.reset();
                                    w.setValues(r.object);
                                    w.show(e.target);
                                }, scope: this
                            }
                        }
                    });
                }, scope: this}
            }
        });

В extende окна:
Ext.extend(Fl.window.UpdateItem, MODx.Window, {

    getFields: function (config) {
        return [{
            xtype: 'hidden',
            name: 'id',
            id: config.id + '-id',
            value: config.id
        },{
            xtype: 'xcheckbox',
            boxLabel: _('fl_lang_active'),
            name: 'active',
            id: config.id + '-active',
            checked: true,
        },
            config.addFields   // ВОТ ТУТ И ДОБАВЛЯЮТСЯ ПОЛЯ, т.е. тот массив полей который передали в ajax запросе
        ];
    },

    loadDropZones: function () {
    }

});
Ext.reg('fl-data-window-update', Fl.window.UpdateItem);
Как то так, наверняка посмотрев через год на этот код будет такая мысль:
«Под чем я был кода писал этот код»
Виктор Долгий
01 сентября 2016, 13:03
2
0
Судя по всему, сохранением опций заведует класс msProductData, вот его и заставим работать. Мой пример с рабочего сайта, где нужно было к значению опции товара нужно было приписать текст. Также можно заменить значение, или обрабатывать поля с несколькими значениями, главное понимать, что нужно делать с массивами (опций):

<?php
$parentCategory = 220;
$optionKey = 'base_nicotine';
$addText = 'мг/мл';

$parents = $modx->runSnippet('pdoResources', array('returnIds' => 1, 'parents' => $parentCategory, 'where' => array('class_key' => 'msCategory'), 'limit' => 0));
$parents = explode(",", $parents);

foreach ($parents as $parent) {
	$products = $modx->getCollection('msProduct', array('parent' => $parent));
	foreach ($products as $product) {
		if (!($product instanceof msProduct)) {
			return "The resource with id = {$product->id} is not instance of msProduct.";
		}
		
		if ($data = $product->getOne('Data')) {
			$options = $data->get('options');
		}
		
		foreach ($options as $dataKey => $dataValue) {
			if ($dataKey == $optionKey && !strpos($dataValue[0], $addText)) {
				$options[$dataKey][0] = $dataValue[0].' '.$addText;
				$data->set('options', $options);
				$data->save();
			}
		}
	}
}

Вот так просто и работает. Над проверками особо не заморачивался, можно допилить, но это уже каждый сам для себя доделает.
Виталий Серый
08 июня 2016, 00:58
7
+3
Можно попробовать обойтись средствами Fenom без getImageList.
{set $rows = json_decode($_modx->resource.tv_product_main_gallery, true)}
{foreach $rows as $row}
    {$row.image}
{/foreach}
Fi1osof
07 января 2016, 11:57
20
+12
Если ключ не хотите светить, то однозначно запрос надо слать с вашего сервера на донора. В MODX есть готовый CURL-клиент. Вот код для примера:
$client = $modx->getService('rest.modRestCurlClient');
$result = $client->request('https://ya.ru', '/', 'POST', $params = array('foo'  => 'foo'));
print $result;
Можете с этим кодом к консоли поиграться.