Completed
Pull Request — master (#37)
by Klochok
04:46
created

InternalObjectCombo   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 5
dl 0
loc 144
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 13 2
A generateConfigs() 0 7 2
A registerChangerScript() 0 7 1
A applyConfigByType() 0 15 4
A findCurrentAttributes() 0 6 1
A applyDefaultAttributes() 0 4 2
B registerSpecialAssets() 0 58 1
1
<?php
2
3
namespace hipanel\widgets\combo;
4
5
use hiqdev\combo\Combo;
6
use ReflectionClass;
7
use yii\base\InvalidConfigException;
8
use yii\bootstrap\Html;
9
use yii\web\View;
10
11
class InternalObjectCombo extends Combo
12
{
13
    /** {@inheritdoc} */
14
    public $type = 'hipanel/object';
15
16
    /** {@inheritdoc} */
17
    public $name;
18
19
    /** {@inheritdoc} */
20
    public $url;
21
22
    /** {@inheritdoc} */
23
    public $_return;
24
25
    /** {@inheritdoc} */
26
    public $_rename;
27
28
    public $_primaryFilter;
29
30
    public $objectsOptions = [];
31
32
    public $currentObjectType;
33
34
    public $currentObjectAttributeName;
35
36
    private $attributes = [];
37
38
    public function init()
39
    {
40
        if (empty($this->objectsOptions)) {
41
            throw new InvalidConfigException('Property `objectsOptions` is required for class ObjectCombo.');
42
        }
43
        $this->inputOptions = ['data-object-selector-field' => true, 'class' => 'object-selector-select'];
44
        $this->registerSpecialAssets();
45
        $this->findCurrentAttributes();
46
        $this->generateConfigs();
47
        parent::init();
48
        $this->registerChangerScript();
49
        $this->applyDefaultAttributes();
50
    }
51
52
    private function generateConfigs()
53
    {
54
        foreach ($this->objectsOptions as $type => $options) {
55
            $this->applyConfigByType($type);
56
        }
57
58
    }
59
60
    private function registerChangerScript()
61
    {
62
        $changerId = Html::getInputId($this->model, $this->currentObjectAttributeName);
63
        $inputId = $this->inputOptions['id'];
64
65
        $this->view->registerJs("initObjectSelectorChanger('{$changerId}', '{$inputId}')");
66
    }
67
68
    private function applyConfigByType($type)
69
    {
70
        $options = $this->objectsOptions[$type];
71
        if ($options['comboOptions']) {
72
            foreach ($this->attributes as $attribute) {
73
                if (isset($options['comboOptions'][$attribute->name])) {
74
                    $this->{$attribute->name} = $options['comboOptions'][$attribute->name];
75
                }
76
            }
77
        }
78
        $this->registerClientConfig();
79
        $varName = strtolower($this->model->formName()) . '_object_id_' . $type;
80
        $id = $this->configId;
81
        $this->view->registerJsVar($varName, $id, View::POS_END);
82
    }
83
84
    private function findCurrentAttributes()
85
    {
86
        $this->attributes = array_filter((new ReflectionClass(get_class($this)))->getProperties(), function ($attr) {
87
            return $attr->class === get_class($this);
88
        });
89
    }
90
91
    private function applyDefaultAttributes()
92
    {
93
        $this->applyConfigByType($this->currentObjectType ?: 'client');
94
    }
95
96
    private function registerSpecialAssets()
97
    {
98
        // Fix validation styles
99
        $this->view->registerCss("
100
            .form-group.has-error .select2-selection { border-color: #dd4b39; box-shadow: none; }
101
            .form-group.has-success .select2-selection { border-color: #00a65a; box-shadow: none; }
102
            select.object-selector-select:not([data-select2-id]) { display: none; }
103
        ");
104
        $this->view->registerJs(<<<'JS'
105
            (function( $ ){
106
107
                var originalDynamicForm = $.fn.yiiDynamicForm;
108
                
109
                var methods = {
110
                    addItem : function(widgetOptions, e, elem) { 
111
                        originalDynamicForm('addItem', widgetOptions, e, elem);
112
                        var count = elem.closest('.' + widgetOptions.widgetContainer).find(widgetOptions.widgetItem).length;
113
114
                        // Reinit ObjectSelectorChanger after added new item
115
                        if (count < widgetOptions.limit) {
116
                            var objectSelectorInputs = $($newclone).find('[data-object-selector-field]');
117
                            if (objectSelectorInputs.length > 0) {
118
                                objectSelectorInputs.each(function() {
119
                                    var objectInputId = $(this).attr('id');
120
                                    var changerInputId = $(this).prev('select').attr('id');
121
                                    initObjectSelectorChanger(changerInputId, objectInputId); 
122
                                });
123
                            }
124
                        } 
125
                    }
126
                };
127
                
128
                $.fn.yiiDynamicForm = function(method) {
129
                    if (method === 'addItem') {
130
                        return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
131
                    } else {
132
                        originalDynamicForm.apply(this, arguments);        
133
                    }
134
                }
135
                
136
            })(window.jQuery);
137
JS
138
        );
139
        $this->view->registerJs(<<<JS
140
            function initObjectSelectorChanger(changerInputId, objectInputId) {
141
                $('#' + changerInputId).change(function(e) {
142
                    var regexID = /^(.+?)([-\d-]{1,})(.+)$/i;
143
                    var matches = objectInputId.match(regexID);
144
                    var combo = $('#' + objectInputId).closest('form').combo();
145
                    if (combo) {
146
                        combo.register('#' + objectInputId, window[matches[1] + '_object_id_' + e.target.value]);
147
                        $('#' + objectInputId).val(null).trigger('change');
148
                    }
149
                });
150
            }
151
JS
152
        );
153
    }
154
}
155