Василий Stepanov

Василий Stepanov

С нами с 10 января 2014; Место в рейтинге пользователей: #159
Василий Stepanov
12 июня 2019, 13:32
+1
Спасибо! Обновился, все работает! Отличный компонент, тестим дальше.
Василий Stepanov
12 июня 2019, 13:16
0
Приветствую.

Подписчики не добавляются в сегменты.
Создал сегмент, добавляю пользователей в этот сегмент, в таблице по этому сегменту пусто. Все добавляются в сегмент с id=0.

В таблице modx_bx_subscriber_segment


Если редактировать каждого подписчика отдельно, то он попадает в нужный сегмент, но получается, что он в двух сегментах: 0 и выбранный.

Журнал ошибок пустой.
Василий Stepanov
12 мая 2019, 15:30
0
смотрел и на DynamicDropdownTV, но у них не работает множественный выбор. Сам множественный выбор исправить удалось, но не полностью. Работает, если только родитель («марки») не имеет множественного выбора (простой select).Знаний, увы, не хватило.
Василий Stepanov
12 мая 2019, 13:16
+1
1.input-box исправь на inputbox.
2. И
container = document.getElementById( 'input-box' );
исправь на
container = document.getElementById( tabs' );
Весь код
<div id="tabs">
    <input name="i-1" type="radio" checked>
    <input name="i-2" type="radio">
    <input name="i-3" type="radio">
</div>
<script>
    window.onload = function () {
        var container, inputbox, i, j;
        
        container = document.getElementById( 'tabs' );    
        inputbox = container.getElementsByTagName( 'input' );
        
        for ( i = 0; i < inputbox.length; i++ ) {
            inputbox[i].addEventListener( 'click', function () {
                for ( j = 0; j < inputbox.length; j++ ) {
                    if ( inputbox[j] !== this ) {
                        inputbox[j].checked = false;
                    }
                }
            }, true );
        }
    };
</script>
Василий Stepanov
27 апреля 2019, 00:24
0
Не уверен, что данный вопрос для вас еще актуален, но я столкнулся с такой же проблемой и нашел решение.

1. В файле /core/components/dynamicdropdowntv/processors/mgr/default/getoptions.default.php нужно заменить
if (!empty($query)) {
	$c->where(array($namefield . ':LIKE' => $query . '%'));
} else {
	$options[] = array('id' => '', 'name' => $firstText);
}
на
if (!empty($query)) {
    $tmp = explode('|', $query);
    $num = true;
    foreach($tmp as $t) {
        $num = ($num && is_numeric($t));
    }

    if($num) {
        $c->where(array($idfield . ':IN' => $tmp) );
    } else {
        $c->where(array($namefield . ':LIKE' => $query . '%'));
    }    
} else {
	$options[] = array('id' => '', 'name' => $firstText);
}

2. Создаем файлы в нужных директориях:
core/components/dynamicdropdowntv/tv/input/dynamicdropdown_mlti.class.php
<?php
/**
 * DynamicDropdownTV
 *
 * Copyright 2012-2013 by Bruno Perner <b.perner@gmx.de>
 *
 * DynamicDropdownTV is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * DynamicDropdownTV is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * DynamicDropdownTV; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * @package dynamicdropdowntv
 * @subpackage input render
 *
 * Input Render for DynamicDropdownTV Multiple
 */
if (!class_exists('DynamicDropdownMultipleInputRender')) {
	class DynamicDropdownMultipleInputRender extends modTemplateVarInputRender {
		public function getTemplate() {
			$corePath = $this->modx->getOption('dynamicdropdowntv.core_path', null, $this->modx->getOption('core_path') . 'components/dynamicdropdowntv/');
			return $corePath . 'tv/input/tpl/dynamicdropdown_mlti.tpl';
		}
		public function process($value, array $params = array()) {
			$corePath = $this->modx->getOption('dynamicdropdowntv.core_path', null, $this->modx->getOption('core_path') . 'components/dynamicdropdowntv/');
			// fetch only the tv lexicon
			$this->modx->lexicon->load('tv_widget');
			$this->modx->lexicon->load('dynamicdropdowntv:inputoptions');
			$lang = $this->modx->lexicon->fetch();
			foreach ($lang as $k => $v) {
				if (strpos($k, 'dynamicdropdowntv.') !== false) {
					$k = str_replace('dynamicdropdowntv.', '', $k);
					$k = str_replace('.', '_', $k);
				}
				$this->setPlaceholder('lang_' . $k, $v);
			}
			$this->setPlaceholder('params', $params);
			$resource = is_object($this->modx->resource) ? $this->modx->resource->toArray() : array();
			$ddId = $this->tv->get('name');
			$groupPath = 'mgr/' . $params['group'];
			$defaultPath = 'mgr/default';
			$actionPath = file_exists($corePath . 'processors/' . $groupPath) ? $groupPath . '/' : $defaultPath . '/';
			if ($this->tv->get('elements') == '') {
				$default_processor = 'getoptions.default';
				$ddProcessor = 'getoptions.' . $ddId;
			} else {
				$default_processor = 'getelements.default';
				$ddProcessor = 'getelements.' . $ddId;
			}
			$action = file_exists($corePath . 'processors/' . $actionPath . $ddProcessor . '.php') ? $actionPath . $ddProcessor : $actionPath . $default_processor;
			$this->setPlaceholder('connector_path', "'" . $this->modx->getOption('dynamicdropdowntv.assets_path', NULL, "' + MODx.config.assets_url + 'components/dynamicdropdowntv/") . "connector.php'");
			$this->setPlaceholder('resource', $resource);
			$this->setPlaceholder('object_id', $this->modx->getOption('object_id', $_REQUEST, ''));
			$this->setPlaceholder('params', $params);
			$this->setPlaceholder('action', $action);
			$this->setPlaceholder('children', $this->modx->toJson(explode(',', $params['childs'])));
			$this->setPlaceholder('parents', $this->modx->toJson(explode(',', $params['parents'])));
			$this->setPlaceholder('ddId', $ddId);
		}
	}
}
return 'DynamicDropdownMultipleInputRender';

core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl
<input type="hidden" id="original{$ddId}" name="original{$tv->id}" value="{$tv->get('value')|escape}" />

<div id="div_{$ddId}">

</div>


<script type="text/javascript">
// <![CDATA[
{literal}
MODx.combo.{/literal}{$ddId}{literal} = function(config) {
    config = config || {};
    Ext.applyIf(config,{{/literal}
        name: '{$ddId}'
        ,id: 'select_{$ddId}'
        ,width: 400
        ,hiddenName: 'tv{$tv->id}[]'
        ,renderTo: 'div_{$ddId}'
        ,triggerAction: 'all'
        ,mode: 'remote'
        ,children: Ext.util.JSON.decode('{$children}')
        ,parents: Ext.util.JSON.decode('{$parents}')
        ,clearBtnCls: 'x-form-trigger'
        ,expandBtnCls: 'x-form-trigger'    
        {if $params.title},title: '{$params.title}'{/if}
        {if $params.listWidth},listWidth: {$params.listWidth}{/if}
        ,maxHeight: {if $params.maxHeight}{$params.maxHeight}{else}300{/if}
        {if $params.typeAhead}
            ,editable: true
            ,typeAhead: true
            ,typeAheadDelay: {if $params.typeAheadDelay && $params.typeAheadDelay != ''}{$params.typeAheadDelay}{else}250{/if}
        {else}
            ,editable: false
            ,typeAhead: false
        {/if}
        {if $params.listEmptyText}
            ,listEmptyText: '{$params.listEmptyText}'
        {/if}
        ,forceSelection: {if $params.forceSelection && $params.forceSelection != 'false'}true{else}false{/if}
        ,initiated: false
        ,allowBlank: {if $params.allowBlank == 1 || $params.allowBlank == 'true'}true{else}false{/if}
		,resizable: false
        ,pageSize: 0		
        ,url: {$connector_path}
        ,fields: ['id','name']
        ,displayField: 'name'
        ,valueField: 'id'
        {if $params.valueDelimiter}
            ,valueDelimiter: '{$params.valueDelimiter}'
        {/if}        
        ,clearOnRefresh: {if $params.clearOnRefresh == 1 || $params.clearOnRefresh == 'true'}true{else}false{/if} 
        {literal}
        ,baseParams: {
            {/literal}
		    action: '{$action}'
            ,resource_id: '{$resource.id}' 
            ,object_id: '{$object_id}'
            ,tvname: '{{$tv->name}}'
            {literal}
        }
        ,store: new Ext.data.JsonStore({
                        id:'id',
                        autoLoad: true,
                        root:'results',
                        fields: ['name', 'id'],
                        remoteSort: true,
                        url: {/literal}{$connector_path}{literal},
                        baseParams:{
                            action: '{/literal}{$action}{literal}'
                            ,resource_id: '{/literal}{$resource.id}{literal}' 
                            ,object_id : '{/literal}{$object_id}{literal}'
                            ,tvname : '{/literal}{{$tv->name}}{literal}' 	                            
                        }
                    }) 
        
        ,listeners: { 
		    'select': {fn:this.selectOption,scope:this}
            ,'additem': {fn:this.selectOption,scope:this}
            ,'removeitem': {fn:this.selectOption,scope:this}
            ,'render': {fn:this.initSelect,scope:this}
		}
    });
    MODx.combo.{/literal}{$ddId}{literal}.superclass.constructor.call(this,config);
};
Ext.extend(MODx.combo.{/literal}{$ddId}{literal},Ext.ux.form.SuperBoxSelect,{
	selectOption: function() {
        if(this.children.length >= 1 && typeof(Ext.getCmp('select_'+this.children[0])) != "undefined") {
            this.refreshChildren(true);
        } 
        MODx.fireResourceFormChange();	         
	}
    ,reload: function() {
        this.store.load({
            callback: function() {
                if (this.clearOnRefresh){
                    this.setValue('');
                }
                this.refreshChildren(true);
            },scope:this
       });
	}
    ,refreshChildren: function(reload) {
        var ddSelect = null;
        for(i = 0; i <  this.children.length; i++) {
 		    child = this.children[i];
            ddSelect = Ext.getCmp('select_'+child);
            if(typeof(ddSelect) != "undefined"){
                ddSelect.baseParams.{/literal}{$ddId}{literal} = this.getValue();
                if (reload){
                    ddSelect.reload();
                }
            }
        }
	}    
    ,initSelect: function() {
        var parent_field = null;
        for(i = 0; i <  this.parents.length; i++) {
 		    parent = this.parents[i];
            parent_field = Ext.get('original'+parent);
            if (parent_field){
                this.store.baseParams[parent] = parent_field.dom.value;
            }
        }
        var original_values = Ext.get('{/literal}original{$ddId}{literal}').dom.value;
        this.setValue(original_values);
        
        // Separate store .. won't fire ever
        this.store.load({
            callback: function() {
                this.setValue(Ext.get('{/literal}original{$ddId}{literal}').dom.value);
            },scope:this
       });
	}
});
Ext.reg('modx-combo-{/literal}{$ddId}{literal}',MODx.combo.{/literal}{$ddId}{literal});
Ext.onReady(function() {
    var fld = MODx.load({
        xtype: 'modx-combo-{/literal}{$ddId}{literal}'
    });
    
    Ext.getCmp('modx-panel-resource').getForm().add(fld);
    {/literal}
});
// ]]>
</script>

core/components/dynamicdropdowntv/tv/inputoptions/dynamicdropdown_mlti.php
<?php
/**
 * DynamicDropdownTV
 *
 * Copyright 2012-2013 by Bruno Perner <b.perner@gmx.de>
 *
 * DynamicDropdownTV is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * DynamicDropdownTV is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * DynamicDropdownTV; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * @package dynamicdropdowntv
 * @subpackage input render properties
 *
 * Input Render for DynamicDropdownTV Properties Multiple
 */
$modx->lexicon->load('tv_widget', 'dynamicdropdowntv:inputoptions');
$lang = $modx->lexicon->fetch('dynamicdropdowntv.', true);
// get list of dynamic dropdown template variables to select parent dropdown
$c = $modx->newQuery('modTemplateVar');
$c->where(array('type:LIKE' => 'dynamicdropdown%'));
$list[] = array('', $lang['noParent']);
if ($collection = $modx->getCollection('modTemplateVar', $c)) {
	foreach ($collection as $object) {
		if ($_REQUEST['tv'] != $object->get('id')) {
			$list[] = array($object->get('name'), $object->get('name'));
		}
	}
}
$list = json_encode($list);
$modx->smarty->assign('tvlist', $list);
$modx->smarty->assign('dynamicdropdowntv', $lang);
$corePath = $modx->getOption('dynamicdropdowntv.core_path', null, $modx->getOption('core_path') . 'components/dynamicdropdowntv/');
return $modx->smarty->fetch($corePath . 'tv/inputoptions/tpl/dynamicdropdown_multiple.tpl');

core/components/dynamicdropdowntv/tv/inputoptions/tpl/dynamicdropdown_mlti.tpl
<div id="tv-input-properties-form{$tv}"></div>
{literal}

<script type="text/javascript">
// <![CDATA[
var params = {
{/literal}{foreach from=$params key=k item=v name='p'}
 '{$k}': '{$v|escape:"javascript"}'{if NOT $smarty.foreach.p.last},{/if}
{/foreach}{literal}
};
var oc = {'change':{fn:function(){Ext.getCmp('modx-panel-tv').markDirty();},scope:this}};

MODx.load({
    xtype: 'panel'
    ,layout: 'form'
    ,cls: 'form-with-labels'
    ,autoHeight: true
    ,border: false
    ,labelAlign: 'top'
    ,labelSeparator: ''
    ,items: [{
        xtype: 'combo'
        ,store : {/literal}{$tvlist}{literal}
        ,fieldLabel: '{/literal}{$dynamicdropdowntv.parent}{literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.parent_desc}{literal}'
        ,name: 'inopt_parent'
        ,hiddenName: 'inopt_parent'
        ,forceSelection: true
        ,typeAhead: false
        ,editable: false
        ,triggerAction: 'all'
        ,id: 'inopt_parent{/literal}{$tv}{literal}'
        ,value: params['parent'] || ''
        ,width: 600
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_parent{/literal}{$tv}{literal}'
        ,html: '{/literal}{$dynamicdropdowntv.parent_desc}{literal}'
        ,cls: 'desc-under'
    },{
        xtype: 'textfield'
        ,fieldLabel: '{/literal}{$dynamicdropdowntv.group}{literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.group_desc}{literal}'
        ,name: 'inopt_group'
        ,hiddenName: 'inopt_group'
        ,id: 'inopt_group{/literal}{$tv}{literal}'
        ,value: params['group']
        ,width: 600
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_group{/literal}{$tv}{literal}'
        ,html: '{/literal}{$dynamicdropdowntv.group_desc}{literal}'
        ,cls: 'desc-under'
    },{
        xtype: 'combo-boolean'
        ,fieldLabel: _('required')
        ,description: MODx.expandHelp ? '' : _('required_desc')
        ,name: 'inopt_allowBlank'
        ,hiddenName: 'inopt_allowBlank'
        ,id: 'inopt_allowBlank{/literal}{$tv}{literal}'
        ,value: params['allowBlank'] == 0 || params['allowBlank'] == 'false' ? false : true
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_allowBlank{/literal}{$tv}{literal}'
        ,html: _('required_desc')
        ,cls: 'desc-under'
    },{
        xtype: 'textfield'
        ,fieldLabel: _('combo_listwidth')
        ,description: MODx.expandHelp ? '' : _('combo_listwidth_desc')
        ,name: 'inopt_listWidth'
        ,id: 'inopt_listWidth{/literal}{$tv}{literal}'
        ,value: params['listWidth'] || ''
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_listWidth{/literal}{$tv}{literal}'
        ,html: _('combo_listwidth_desc')
        ,cls: 'desc-under'
    },{
        xtype: 'combo-boolean'
        ,fieldLabel: _('combo_typeahead')
        ,description: MODx.expandHelp ? '' : _('combo_typeahead_desc')
        ,name: 'inopt_typeAhead'
        ,hiddenName: 'inopt_typeAhead'
        ,id: 'inopt_typeAhead{/literal}{$tv}{literal}'
        ,value: params['typeAhead'] == 1 || params['typeAhead'] == 'true' ? true : false
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_typeAhead{/literal}{$tv}{literal}'
        ,html: _('combo_typeahead_desc')
        ,cls: 'desc-under'
    },{
        xtype: 'textfield'
        ,fieldLabel: _('combo_typeahead_delay')
        ,description: MODx.expandHelp ? '' : _('combo_typeahead_delay_desc')
        ,name: 'inopt_typeAheadDelay'
        ,id: 'inopt_typeAheadDelay{/literal}{$tv}{literal}'
        ,value: params['typeAheadDelay'] || 250
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_typeAheadDelay{/literal}{$tv}{literal}'
        ,html: _('combo_typeahead_delay_desc')
        ,cls: 'desc-under'

    },{
        xtype: 'combo-boolean'
        ,fieldLabel: _('combo_forceselection')
        ,description: MODx.expandHelp ? '' : _('combo_forceselection_desc')
        ,name: 'inopt_forceSelection'
        ,hiddenName: 'inopt_forceSelection'
        ,id: 'inopt_forceSelection{/literal}{$tv}{literal}'
        ,value: params['forceSelection'] == 1 || params['forceSelection'] == 'true' ? true : false
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_forceSelection{/literal}{$tv}{literal}'
        ,html: _('combo_forceselection_desc')
        ,cls: 'desc-under'

    },{
        xtype: 'textfield'
        ,fieldLabel: '{/literal}{$dynamicdropdowntv.firstText}{literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.firstText_desc}{literal}'
        ,name: 'inopt_firstText'
        ,id: 'inopt_firstText{/literal}{$tv}{literal}'
        ,value: params['firstText'] || ''
        ,anchor: '100%'
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_firstText{/literal}{$tv}{literal}'
        ,html: '{/literal}{$dynamicdropdowntv.firstText_desc}{literal}'
        ,cls: 'desc-under'
    },{
        xtype: 'combo-boolean'
        ,fieldLabel:'{/literal}{$dynamicdropdowntv.clearOnRefresh}{literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.clearOnRefresh_desc}{literal}'
        ,name: 'inopt_clearOnRefresh'
        ,hiddenName: 'inopt_clearOnRefresh'
        ,id: 'inopt_clearOnRefresh{/literal}{$tv}{literal}'
        ,value: params['clearOnRefresh'] || true
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_clearOnRefresh{/literal}{$tv}{literal}'
        ,html: '{/literal}{$dynamicdropdowntv.clearOnRefresh_desc}{literal}'
        ,cls: 'desc-under'
    },{
        xtype: 'textfield'
        ,fieldLabel:'{/literal}{$dynamicdropdowntv.valueDelimiter}{literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.valueDelimiter_desc}{literal}'
        ,name: 'inopt_valueDelimiter'
        ,id: 'inopt_valueDelimiter{/literal}{$tv}{literal}'
        ,value: params['valueDelimiter'] || '||'
        ,width: 200
        ,listeners: oc
    },{
        xtype: MODx.expandHelp ? 'label' : 'hidden'
        ,forId: 'inopt_valueDelimiter{/literal}{$tv}{literal}'
        ,html:'{/literal}{$dynamicdropdowntv.valueDelimiter_desc}{literal}'
        ,cls: 'desc-under'
    },{
        xtype: 'fieldset'
        ,fieldLabel: '{/literal}{$dynamicdropdowntv.package}{literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.package_desc}{literal}'
        ,labelAlign: 'top'
		,items: [{
			xtype: 'textarea'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.where}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.where_desc}{literal}'
			,name: 'inopt_where'
			,hiddenName: 'inopt_where'
			,id: 'inopt_where{/literal}{$tv}{literal}'
			,value: params['where']
			,width: 600
			,height: 150
			,listeners: oc
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_where{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.where_desc}{literal}'
			,cls: 'desc-under'
		},{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.packagename}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.packagename_desc}{literal}'
			,name: 'inopt_packagename'
			,id: 'inopt_packagename{/literal}{$tv}{literal}'
			,value: params['packagename']
			,anchor: '100%'
			,listeners: oc
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_packagename{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.packagename_desc}{literal}'
			,cls: 'desc-under'
		},{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.prefix}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.prefix_desc}{literal}'
			,name: 'inopt_prefix'
			,id: 'inopt_prefix{/literal}{$tv}{literal}'
			,value: params['prefix']
			,anchor: '100%'
			,listeners: oc
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_prefix{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.prefix_desc}{literal}'
			,cls: 'desc-under'
		},{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.classname}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.classname_desc}{literal}'
			,name: 'inopt_classname'
			,id: 'inopt_classname{/literal}{$tv}{literal}'
			,value: params['classname']
			,anchor: '100%'
			,listeners: oc
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_classname{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.classname_desc}{literal}'
			,cls: 'desc-under'
		},{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.idfield}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.idfield_desc}{literal}'
			,name: 'inopt_idfield'
			,id: 'inopt_idfield{/literal}{$tv}{literal}'
			,value: params['idfield']
			,anchor: '100%'
			,listeners: oc
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_idfield{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.idfield_desc}{literal}'
			,cls: 'desc-under'
		},{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.namefield}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.namefield_desc}{literal}'
			,name: 'inopt_namefield'
			,id: 'inopt_namefield{/literal}{$tv}{literal}'
			,value: params['namefield']
			,anchor: '100%'
			,listeners: oc
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_namefield{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.namefield_desc}{literal}'
			,cls: 'desc-under'
		}]
    },{
        xtype: 'fieldset'
        ,fieldLabel: '{/literal}{$dynamicdropdowntv.debugfields} ({$dynamicdropdowntv.readonly}){literal}'
        ,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.debugfields_desc}{literal}'
        ,labelAlign: 'top'
		,items: [{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.childs}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.childs_desc}{literal}'
			,name: 'inopt_childs'
			,hiddenName: 'inopt_childs'
			,id: 'inopt_childs{/literal}{$tv}{literal}'
			,value: params['childs']
			,width: 600
			,listeners: oc
			,readOnly: true
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_childs{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.childs_desc}{literal}'
			,cls: 'desc-under'
		},{
			xtype: 'textfield'
			,fieldLabel: '{/literal}{$dynamicdropdowntv.parents}{literal}'
			,description: MODx.expandHelp ? '' : '{/literal}{$dynamicdropdowntv.parents_desc}{literal}'
			,name: 'inopt_parents'
			,hiddenName: 'inopt_parents'
			,id: 'inopt_parents{/literal}{$tv}{literal}'
			,value: params['parents']
			,width: 600
			,listeners: oc
			,readOnly: true
		},{
			xtype: MODx.expandHelp ? 'label' : 'hidden'
			,forId: 'inopt_parents{/literal}{$tv}{literal}'
			,html: '{/literal}{$dynamicdropdowntv.parents_desc}{literal}'
			,cls: 'desc-under'
		}]
	}]
    ,renderTo: 'tv-input-properties-form{/literal}{$tv}{literal}'
});
// ]]>
</script>
{/literal}

3. Чистим папку cache.
4. Используем TV-поле dynamicdropdown_mlti.
ВНИМАНИЕ: при обновлении компонента изменения удалятся.

Источники:
1. https://github.com/Bruno17/DynamicDropdownTV/issues/9
2. https://github.com/nicar/DynamicDropdownTV/commit/62caff3c3f842efc4f21b123195238a411783207#diff-c621b98b2d9f7f81dbd76642657e04ac
Василий Stepanov
04 февраля 2018, 01:32
0
Решил так.
1. Сформировал ICML-файл, согласно документации
В моем случае параметры id и productId в элементах
<offer>
имеют значение id товара на сайте.
2. Загрузил его в базу товаров RetailCRM (Администрирование -> Магазины -> Ваш_магазин -> Каталог: указываем url вашего ICML-файла, ставим галку «Загрузить каталог из ICML сейчас» и жмем сохранить).
И так нужно делать каждый раз, после добавления товаров на вашем сайте (другого решения пока не нашел)
3. В плагине modRetailCRM заменил этот код
foreach ($order['products'] as $key=>$product) {
   /* данные товаров в заказе */
}

на этот
foreach ($order['products'] as $key=>$product) {
   $orderData['items'][$key]['initialPrice'] = $product['price'];
   $orderData['items'][$key]['purchasePrice'] = $product['price'];
   $orderData['items'][$key]['offer']['externalId'] = $product['product_id'];
   $orderData['items'][$key]['quantity'] = $product['count'];
}

Теперь при создании заказа, товары добавляются в заказ из базы crm в соответствии с id товара в моем магазине
Василий Stepanov
31 января 2018, 09:21
0
Спасибо, как раз созданием товара и занимаюсь. Поделюсь, если что получится.
Василий Stepanov
30 января 2018, 19:20
0
И артикул добавил через свойства (зел.), как вписать его в поле Артикул crm (красн.)?
Василий Stepanov
30 января 2018, 19:07
0
Спасибо, что обратили внимание на мой комментарий.
Основная проблема в том, что в crm не создаются товары на складе
Василий Stepanov
30 января 2018, 18:49
0
Со свойствами понял: их у меня у товаров просто нет. Но тогда возникает вопрос: как передать артикул, чтобы он в crm был именно артикулом, а не свойством
Василий Stepanov
30 января 2018, 18:36
0
Заказы передаются, покупатели тоже.
Не создается товар складе и не указываются свойства товара.
Для примера в плагине написал
$orderData['items'][$key]['properties'][] = array('name' => 'Артикул', 'value' => '06512');
так сработало, свойство «Артикул» появилось.

Подскажите, что не так делаю?
Василий Stepanov
06 июля 2017, 15:52
0
Сделал себе тоже такой чекбокс. Можно тут протестировать http://naukograd28.ru/stroitelyam-kosmodroma...
Василий Stepanov
06 июля 2017, 15:47
0
Помогло?)
Василий Stepanov
06 июля 2017, 13:28
+1
Можно сделать так:
1. Добавляем чекбокс в форму добавления комментария. Для этого редактируем чанк tpl.Tickets.comment.form.guest.
После
<div class="form-group">
	<label for="comment-email">[[%ticket_comment_email]]</label>
	<input type="text" name="email" value="[[+email]]" requiredid="comment-email" class="form-control" />
	<span class="error"></span>
</div>

добавляем наш чекбокс:
<div class="form-group"> 
	<label for="comment-pdata"><input name="comment-pdata" id="comment-pdata" type="checkbox"> Даю свое согласие на обработку персональных данных</label>
	<span class="error"></span>
</div>
Жмем Сохранить.

2. Создаем плагин ticketsCommentPersonalDate:

if ($modx->event->name == 'OnBeforeCommentSave') {
	if (!isset($_REQUEST['comment-pdata'])) { 
		$modx->event->output('Вы не дали согласие на обработку персональных данных');
	}
}

И в системных событиях плагина не забываем поставить галочку напротив события OnBeforeCommentSave.
Жмем Сохранить.

Теперь, если при добавлении коммента пользователь не поставит галочку, то всплывет предупреждение справа сверху и коммент не добавится.
Василий Stepanov
05 июля 2017, 16:27
0
Переделал. Не уверен, что все правильно сделал, но работает в разы быстрее.
Условия выборки немного изменились: вывести статьи, у которых просмотров меньше 20, количество комментов = 0, и, которые опубликованы больше трех недель назад.
$week = 604800;
$cond_date = strtotime('now')-$week*3;

$q_test = " SELECT 
                modx_site_content.id, 
                modx_site_content.properties, 
                modx_site_content.publishedon,
                modx_tickets_threads.comments 
            FROM 
                `modx_site_content`, 
                `modx_tickets_threads` 
            WHERE 
                modx_site_content.id = modx_tickets_threads.resource 
                AND 
                modx_site_content.parent = '19'";

$result = $modx->query($q_test);
$rows = $result->fetch();

do {
    $id = $rows['id'];
    $comments = $rows['comments'];
    $date = $rows['publishedon'];
    $visits = preg_replace("/[^0-9]/", '', $rows['properties']);
    
    if ($comments == 0 and $visits <= 20 and $date < $cond_date) {
        echo "<pre>";
        echo "id = ". $id. "<br />";
        echo "comments = ". $comments. "<br />";
        echo "pubdate = ". date("Y-m-d",$date). "<br />";
        echo "visits = ". $visits;
        echo "</pre>";
    }
}
while ($rows = $result->fetch());
Василий Stepanov
04 июня 2017, 03:50
1
0
Добрый день!
Например, miniShop2 + mspSberbank, если вы ИП. Если физ. лицо, то вместо mspSberbank используйте ЯД mspYandexMoney.
Василий Stepanov
28 мая 2017, 13:56
0
Нашел ошибку! Нужно
// записываем в поле photo
$profile->set('photo', $folder.$NewNameFile);
$profile->save();
Заменить на
// записываем в наш тв
$resource->setTVValue($tv_name, $folder.$NewNameFile);
Василий Stepanov
27 мая 2017, 09:59
+1
Комментарии пользователя я вывожу так:
[[!TicketLatest? 
	&limit=`5` 
	&tpl=`tplTtCom.list`
	&fastMode=`1` 
	&action=`comments` 
	&user=`[[!+modx.user.id:userinfo=`id`]]` 
]]
Василий Stepanov
24 мая 2017, 12:10
1
+1
Проблема № 1 При загрузке изображения с расширением .png, прозрачный фон заменяется на черный. решена!
При ресемплировании выключаем режим сопряжения цветов и включаем сохранение альфаканала:
//Отключаем режим сопряжения цветов
imagealphablending($image_p, false);
//Включаем сохранение альфа канала
imagesavealpha($image_p, true);
И в зависимости от расширения исходного файла сохраняем изображение:
// сохраняем изображение в папку
if ($typeFile == 'image/jpeg')
imagejpeg($image_p, $path.$NewNameFile, 100);
elseif ($typeFile == 'image/png')
imagepng($image_p, $path.$NewNameFile);
else
return false;
Чтобы ввесь код сюда не копировать, замените условие if ($width > $max_width) {...} на следующее:
if ($width > $max_width) {
	// получение новых размеров
	$ratio = $width/$max_width;
	$new_width = round($width/$ratio);
	$new_height = round($height/$ratio);
                    
	// ресэмплирование
	$image_p = imagecreatetruecolor($new_width, $new_height);

	//Отключаем режим сопряжения цветов
	imagealphablending($image_p, false);
	//Включаем сохранение альфа канала
	imagesavealpha($image_p, true);
                    
	imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
                    
	// сохраняем изображение в папку
	if ($typeFile == 'image/jpeg')
	imagejpeg($image_p, $path.$NewNameFile, 100);
	elseif ($typeFile == 'image/png')
	imagepng($image_p, $path.$NewNameFile);
	else
	return false;
                    
	// записываем в поле photo
	$profile->set('photo', $folder.$NewNameFile);
	$profile->save();
}