DocentBF

DocentBF

С нами с 19 мая 2015; Место в рейтинге пользователей: #72
DocentBF
16 февраля 2017, 10:55
+1
CREATE, ALTER тоже точно нужны, например, при установке обновлений MODX или дополнений.
DocentBF
16 февраля 2017, 09:51
2
+1
На примере CSV.
1. Создаем кнопку, например, в верхнем баре:
getTopBar: function() { return [{
            text: '<i class="icon icon-chevron-up"></i> ' + _('modExtra_items_export'),
            handler: this.exportCSV, // функция-обработчик кнопки
            scope: this
}]

2. Добавляем виджет-окно импорта с выбором файла:
modExtra.window.ImportCSV = function(config) {
    config = config || {};
    this.ident = config.ident || 'modextra'+Ext.id();
    Ext.applyIf(config,{
        title: _('modextra_items_import')
        ,id: this.ident
        ,fileUpload: true
        ,autoHeight: true
        ,width: 650
        ,url: modExtra.config.connector_url
        ,action: 'mgr/item/import' // процессор загрузки и обработки файла, находится по пути modExtra/processors/mgr/item/import.class.php
        ,fields: [
            {
                xtype: 'fileuploadfield',
                fieldLabel: _('modextra_window_import_file'),
                allowBlank: false
            }
        ]
        ,keys: [
            {
                key: Ext.EventObject.ENTER
                ,shift: true
                ,fn: function() {this.submit() }
                ,scope: this
            }
        ]
    });
    modExtra.window.ImportCSV.superclass.constructor.call(this,config);
};
Ext.extend(modExtra.window.ImportCSV,MODx.Window);
Ext.reg('modextra-window-import-csv',modExtra.window.ImportCSV);
3. Создаете handler кнопки, расширяя grid:
Ext.extend(modExtra.grid.Items, MODx.grid.Grid, {
    windows: {},
    importCSV: function (btn, e) {
        if (!this.windows.ImportCSV) {
            this.windows.ImportCSV = MODx.load({
                xtype: 'modextra-window-import-csv'
                ,listeners: {
                    'success': {fn:function(){this.refresh();},scope:this}
                    ,'failure': {fn:function(){console.log("error")}}
                }
            });
        }
        this.windows.ImportCSV.fp.getForm().reset();
        this.windows.ImportCSV.show(e.target);
    },
    ...
4. Создаем процессор импорта (/core/components/modextra/processors/mgr/item/import.class.php):
<?php
/**
 *  Import
 */
include_once MODX_CORE_PATH . 'model/modx/processors/browser/file/upload.class.php';
class modExtraImportProcessor extends modBrowserFileUploadProcessor {
    public $objectType = 'modExtraItem';
    public $classKey = 'modExtraItem';
    public $languageTopics = array('modExtra');

    public function initialize() {
        $this->setDefaultProperties(array(
            'source' => 0,
            'path' => 'assets/components/modExtra/files/',
        ));
        if (!$this->getProperty('path')) return $this->modx->lexicon('file_folder_err_ns');
        return true;
    }

    /** {inheritDoc} */
    public function process(){
        if (!$this->getSource()) {
            return $this->failure($this->modx->lexicon('permission_denied'));
        }
        $this->source->setRequestProperties($this->getProperties());
        $this->source->initialize();
        $this->source->setProperties(array('basePath'=>''));
        if (!$this->source->checkPolicy('create')) {
            return $this->failure($this->modx->lexicon('permission_denied'));
        }
        $success = $this->source->uploadObjectsToContainer($this->getProperty('path'),$_FILES);
        $file_n = current($_FILES);
        $file = is_array($_FILES) ? $file_n['name'] : false;

        if (empty($success) || !$file) {
            $msg = '';
            $errors = $this->source->getErrors();
            foreach ($errors as $k => $msg) {
                $this->modx->error->addField($k,$msg);
            }
            return $this->failure($msg);
        } else {
            $file = $_SERVER['DOCUMENT_ROOT'].'/'.$this->getProperty('path').$file;
            if(($handle = fopen($file,"r"))) {
                while(($data = fgetcsv($handle,null,';'))) {
                    /*
                        Далее код разборки CSV и сохранение нового объекта
                        $rec = $modx->newObject();
                        $rec->set('field', $data[$n])
                        $rec->save();
                    */                    
                }
                @unlink($file);
            }
        }
        return $this->success();
    }


}

return 'modExtraImportProcessor';
Код написан на скорую руку, может быть кто-то поправит?)
DocentBF
15 декабря 2016, 15:41
0
Не выходит, получается, что к массиву groupby в msProducts добавляется еще один элемент.
DocentBF
15 декабря 2016, 14:12
0
Лог
0.0024860: pdoTools loaded.
0.0000570: Conditions prepared
0.0000150: xPDO query object created
0.0000570: leftJoined msProductData as Data
0.0000379: leftJoined msVendor as Vendor
0.0000372: leftJoined msProductFile as 240x180
0.0000010: Grouped by msProduct.id, `240x180`.url
0.0000172: Added selection of msProduct: SQL_CALC_FOUND_ROWS `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
0.0000081: Added selection of msProductData: `article`, `price`, `old_price`, `weight`, `image`, `thumb`, `vendor`, `made_in`, `new`, `popular`, `favorite`, `tags`, `color`, `size`, `source`
0.0000060: Added selection of msVendor: `name` AS `vendor.name`, `resource` AS `vendor.resource`, `country` AS `vendor.country`, `logo` AS `vendor.logo`, `address` AS `vendor.address`, `phone` AS `vendor.phone`, `fax` AS `vendor.fax`, `email` AS `vendor.email`, `description` AS `vendor.description`, `properties` AS `vendor.properties`
0.0000041: Added selection of msProductFile: url as `240x180`
0.0000091: Processed additional conditions
0.0000639: Added where condition: class_key=msProduct, msProduct.id:IN(5,5,6), msProduct.published=1, msProduct.deleted=0
0.0000200: Sorted by msProduct.id, ASC
0.0001140: SQL prepared "SELECT SQL_CALC_FOUND_ROWS `msProduct`.`id`, `msProduct`.`type`, `msProduct`.`contentType`, `msProduct`.`pagetitle`, `msProduct`.`longtitle`, `msProduct`.`description`, `msProduct`.`alias`, `msProduct`.`link_attributes`, `msProduct`.`published`, `msProduct`.`pub_date`, `msProduct`.`unpub_date`, `msProduct`.`parent`, `msProduct`.`isfolder`, `msProduct`.`introtext`, `msProduct`.`richtext`, `msProduct`.`template`, `msProduct`.`menuindex`, `msProduct`.`searchable`, `msProduct`.`cacheable`, `msProduct`.`createdby`, `msProduct`.`createdon`, `msProduct`.`editedby`, `msProduct`.`editedon`, `msProduct`.`deleted`, `msProduct`.`deletedon`, `msProduct`.`deletedby`, `msProduct`.`publishedon`, `msProduct`.`publishedby`, `msProduct`.`menutitle`, `msProduct`.`donthit`, `msProduct`.`privateweb`, `msProduct`.`privatemgr`, `msProduct`.`content_dispo`, `msProduct`.`hidemenu`, `msProduct`.`class_key`, `msProduct`.`context_key`, `msProduct`.`content_type`, `msProduct`.`uri`, `msProduct`.`uri_override`, `msProduct`.`hide_children_in_tree`, `msProduct`.`show_in_tree`, `msProduct`.`properties`, `Data`.`article`, `Data`.`price`, `Data`.`old_price`, `Data`.`weight`, `Data`.`image`, `Data`.`thumb`, `Data`.`vendor`, `Data`.`made_in`, `Data`.`new`, `Data`.`popular`, `Data`.`favorite`, `Data`.`tags`, `Data`.`color`, `Data`.`size`, `Data`.`source`, `Vendor`.`name` AS `vendor.name`, `Vendor`.`resource` AS `vendor.resource`, `Vendor`.`country` AS `vendor.country`, `Vendor`.`logo` AS `vendor.logo`, `Vendor`.`address` AS `vendor.address`, `Vendor`.`phone` AS `vendor.phone`, `Vendor`.`fax` AS `vendor.fax`, `Vendor`.`email` AS `vendor.email`, `Vendor`.`description` AS `vendor.description`, `Vendor`.`properties` AS `vendor.properties`, `240x180`.url as `240x180` FROM `cHJJ22EjWdO5_site_content` AS `msProduct` LEFT JOIN `cHJJ22EjWdO5_ms2_products` `Data` ON `msProduct`.`id` =  `Data`.`id` LEFT JOIN `cHJJ22EjWdO5_ms2_vendors` `Vendor` ON Data.vendor=Vendor.id LEFT JOIN `cHJJ22EjWdO5_ms2_product_files` `240x180` ON `240x180`.product_id = msProduct.id AND `240x180`.rank = 0 AND `240x180`.path LIKE '%/240x180/%' WHERE  ( `msProduct`.`class_key` = 'msProduct' AND `msProduct`.`id` IN (5,5,6) AND `msProduct`.`published` = 1 AND `msProduct`.`deleted` = 0 )  GROUP BY msProduct.id, `240x180`.url ORDER BY msProduct.id ASC "
0.0004880: SQL executed
0.0000429: Total rows: 3
0.0000131: Rows fetched
0.0000200: Returning raw data
0.0005660: Checked the active modifiers
0.0018320: Loaded "modChunk" with name "tpl.msProducts.row"
0.0054190: Compiled Fenom chunk with name "modchunk/2"
0.0015728: Time to load products options
0.0317070: Total time
6 291 456: Memory usage
DocentBF
31 октября 2016, 23:52
1
+2
Попробуйте вынести условие:
{if $_modx->resource.parent|in:[23,27,24,26,25,29,30,28]}{set $cond = $_modx->resource.parent}
{else}
{set $cond = $_modx->resource.id}
{/if}
{$_modx->runSnippet('!pdoMenu', [
'parents'=>$cond,
...
Или уберите кавычки из параметра parents, получается, что туда идет строка, а не результат условия.
DocentBF
31 июля 2016, 00:56
0
Напишите свои контакты, есть минимум 2 решения.
DocentBF
06 июля 2016, 00:48
0
Сделаем. Как можно с вами связаться?
DocentBF
30 июня 2016, 00:35
+1
1.Вы можете написать сниппет и вызывать в чанке письма, например, так: [[!exampleFormat? &example=`[[+example]]`]].
2.Никто не запрещает посмотреть $_POST['example'], там будет массив значений.
3.Можно написать hook для FormIt. $hook->getValues(), а дальше делайте, что хотите.
DocentBF
28 июня 2016, 21:39
0
Пишите в личку, что-нибудь придумаем
DocentBF
25 июня 2016, 20:36
4
+4
Можно переписать метод mSearch2.handleSort или подключить к mFilter2 cвой скрипт фронтенда или переопределить метод в другом js файле, например как-то так:
if (typeof(mSearch2) !== "undefined") {
mSearch2.initialized = false;
mSearch2.handleSort = function() {
    var params = this.Hash.get();
    if (params.sort) {
            var sorts = params.sort.split(mse2Config.values_delimeter);
            for (var i = 0; i < sorts.length; i++) {
                var tmp = sorts[i].split(mse2Config.method_delimeter);
                if (tmp[0] && tmp[1]) {
                    $('#mse2_sort option[data-sort="' + tmp[0] + '"][value="' + tmp[1] + '"]').attr('selected', 'selected').trigger('change');
                }
            }
        }
        $(document).off('click', this.options.sort_link);
        $(document).on('change', '#mse2_sort', function() {
            var selected = $(this).find('option:selected');
            var sort = selected.data('sort');
            sort += mse2Config.method_delimeter + selected.val();
            mse2Config.sort = (sort != mse2Config.start_sort) ? sort : '';
            var params = mSearch2.getFilters();
            mSearch2.Hash.set(params);
            mSearch2.load(params);
        });
    }
    mSearch2.initialize('body');
}
а select представить например так:
<select id="mse2_sort">
    <option value="asc" data-sort="resource|pagetitle">по умолчанию</option>
    <option value="asc" data-sort="ms|price">по возрастанию цены</option>
    <option value="desc" data-sort="ms|price">по убыванию цены</option>
</select>
DocentBF
24 июня 2016, 19:22
0
Ссылка идёт с поддоменом или с доп. вложенностью? Плагин настроили?
DocentBF
24 июня 2016, 19:13
1
+2
Не знаю, как у вас написан сниппет, но возможно, у вас там нет подстановки знака %, получается проверка на строгое совпадение, т.е. вместо field LIKE '%value%' у вас field LIKE 'value', попробуйте {«Data.kolichestvodverei:LIKE»:"%[[!text_to_json? &text=`[[!*the_number_of_doors]]`]]%"}
DocentBF
24 июня 2016, 10:42
+1
Если у вас уже есть объект, то переходите к leftJoin, иначе создайте схему и объектную модель, например вручную или с помощью migx (проще, на мой взгляд) или cmp generator .
Схема будет приблизительно такая:
<?xml version="1.0" encoding="UTF-8"?>
<model package="StarRating" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
        <object class="StarRating" table="star_rating" extends="xPDOSimpleObject">
                <field key="star_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false"/> 
                <field key="group_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false"/>                
                <field key="vote_total" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false"/>                
                <field key="vote_count" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false"/>                
        </object>
</model>
Затем используйте параметр &leftJoin
&leftJoin=`{
	"StarRating": {
		"class": "StarRating",
		"on": "modResource.id = StarRating.star_id"
	},
}`
и сортируйте).
Или же напишите сниппет для выборки из таблицы.
DocentBF
23 июня 2016, 23:13
1
+5
Может быть потому, что в pdoResources по-умолчанию:
&limit=`10`
Показывайте вызов и вывод &showLog=`1`
DocentBF
23 июня 2016, 17:58
2
+3
Сделайте, например, так:
if($modx->event->name != "OnDocFormSave") {return '';}
$tv1 = $resource->getTVValue('tv1');
$tv2 = $resource->getTVValue('tv2');
$pagetitle = $tv1."-".$tv2;
$resource->set('pagetitle',$pagetitle);
$resource->save();
DocentBF
20 июня 2016, 15:08
0
@Prihod, есть проблема с импортом в файлах, где используются многострочные ячейки, например, это требуется при загрузке поля content. Возможно я что-то недоглядел в настройках, но решил проблему заменой построчного считывания файла на fgetcsv:
// msie.class.php:~1820
... else {
	$handle = fopen($file, "r");
	...
	//for($i=$start;$i< $stop; $i++) {
	while($csv = fgetcsv($handle, filesize($file), $delimeter)) {
		if($out['rows']>= $stop) {
			break;
		}
		if($out['rows']) < $start) {
			$out['rows']++;
			continue;
		}
		...
	}
	fclose($handle);
DocentBF
17 марта 2016, 11:48
1
0
Сортировка по pagetitle, скорее всего, не спасет, т.к. поле типа varchar и вывод будет таким же, как показано выше. В данном случае можно попробовать убрать параметр sortby и использовать where c преобразованием типа:
&where=`["ORDER BY CAST(pagetitle AS SIGNED)  ASC"]`
Могу ошибаться, нужно пробовать.
DocentBF
20 мая 2015, 14:31
0
Подготавливайте вывод в процессоре.
Можно какой-либо пример или ссылку?