Completed
Push — master ( 89011d...ce8f51 )
by Klochok
03:44
created

IndexPage::getUiModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 6
1
<?php
2
/**
3
 * HiPanel core package.
4
 *
5
 * @link      https://hipanel.com/
6
 * @package   hipanel-core
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2014-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\widgets;
12
13
use hipanel\models\IndexPageUiOptions;
14
use Yii;
15
use yii\base\InvalidParamException;
16
use yii\base\Model;
17
use yii\base\Widget;
18
use yii\bootstrap\ButtonDropdown;
19
use yii\data\DataProviderInterface;
20
use yii\helpers\Html;
21
use yii\helpers\Inflector;
22
use yii\helpers\Json;
23
use yii\helpers\Url;
24
use yii\web\View;
25
26
class IndexPage extends Widget
27
{
28
    /**
29
     * @var string
30
     */
31
    protected $_layout;
32
33
    /**
34
     * @var Model the search model
35
     */
36
    public $model;
37
38
    /**
39
     * @var IndexPageUiOptions
40
     */
41
    private $uiModel;
42
43
    /**
44
     * @var object original view context.
45
     * It is used to render sub-views with the same context, as IndexPage
46
     */
47
    public $originalContext;
48
49
    /**
50
     * @var DataProviderInterface
51
     */
52
    public $dataProvider;
53
54
    /**
55
     * @var array Hash of document blocks, that can be rendered later in the widget's views
56
     * Blocks can be set explicitly on widget initialisation, or by calling [[beginContent]] and
57
     * [[endContent]]
58
     *
59
     * @see beginContent
60
     * @see endContent
61
     */
62
    public $contents = [];
63
64
    /**
65
     * @var string the name of current content block, that is under the render
66
     * @see beginContent
67
     * @see endContent
68
     */
69
    protected $_current = null;
70
71
    /**
72
     * @var array
73
     */
74
    public $searchFormData = [];
75
76
    /**
77
     * @var array
78
     */
79
    public $searchFormOptions = [];
80
81
    /**
82
     * @var string the name of view file that contains search fields for the index page. Defaults to `_search`
83
     * @see renderSearchForm()
84
     */
85
    public $searchView = '_search';
86
87
    /** {@inheritdoc} */
88
    public function init()
89
    {
90
        parent::init();
91
        $searchFormId = Json::htmlEncode("#{$this->getBulkFormId()}");
92
        $this->originalContext = Yii::$app->view->context;
93
        $view = $this->getView();
94
        // Fix a very narrow select2 input in the search tables
95
        $view->registerCss('#content-pjax .select2-dropdown--below { min-width: 170px!important; }');
96
        $view->registerJs(<<<"JS"
97
        // Checkbox
98
        var checkboxes = $('table input[type="checkbox"]');
99
        var bulkcontainer = $('.box-bulk-actions fieldset');
100
        checkboxes.on('ifChecked ifUnchecked', function(event) {
101
            if (event.type == 'ifChecked' && $('input.icheck').filter(':checked').length > 0) {
102
                bulkcontainer.prop('disabled', false);
103
            } else if ($('input.icheck').filter(':checked').length == 0) {
104
                bulkcontainer.prop('disabled', true);
105
            }
106
        });
107
        // On/Off Actions TODO: reduce scope
108
        $(document).on('click', '.box-bulk-actions a', function (event) {
109
            var link = $(this);
110
            var action = link.data('action');
111
            var form = $($searchFormId);
112
            if (action) {
113
                form.attr({'action': action, method: 'POST'}).submit();
114
            }
115
        });
116
        // Fix on clear select2 fields 
117
        // $(document).on('pjax:complete', function() {
118
        //     var els = $(':input[data-combo-field]');
119
        //     els.each(function() {
120
        //         var el = $(this);
121
        //         el.select2('close');
122
        //     });
123
        // });
124
        // Do not open select2 when clear
125
        var el = $(':input[data-combo-field]');
126
        el.on('select2:unselecting', function(e) {
127
            el.data('unselecting', true);
128
        }).on('select2:open', function(e) { // note the open event is important
129
            if (el.data('unselecting')) {
130
                el.removeData('unselecting'); // you need to unset this before close
131
                el.select2('close');
132
            }
133
        });
134
JS
135
        );
136
    }
137
138
    public function getUiModel()
139
    {
140
        if ($this->uiModel === null) {
141
            $this->uiModel = $this->originalContext->indexPageUiOptionsModel;
142
        }
143
144
        return $this->uiModel;
145
    }
146
147
    /**
148
     * Begins output buffer capture to save data in [[contents]] with the $name key.
149
     * Must not be called nested. See [[endContent]] for capture terminating.
150
     * @param string $name
151
     */
152
    public function beginContent($name)
153
    {
154
        if ($this->_current) {
155
            throw new InvalidParamException('Output buffer capture is already running for ' . $this->_current);
156
        }
157
        $this->_current = $name;
158
        ob_start();
159
        ob_implicit_flush(false);
160
    }
161
162
    /**
163
     * Terminates output buffer capture started by [[beginContent()]].
164
     * @see beginContent
165
     */
166
    public function endContent()
167
    {
168
        if (!$this->_current) {
169
            throw new InvalidParamException('Outout buffer capture is not running. Call beginContent() first');
170
        }
171
        $this->contents[$this->_current] = ob_get_contents();
172
        ob_end_clean();
173
        $this->_current = null;
174
    }
175
176
    /**
177
     * Returns content saved in [[content]] by $name.
178
     * @param string $name
179
     * @return string
180
     */
181
    public function renderContent($name)
182
    {
183
        return $this->contents[$name];
184
    }
185
186
    public function run()
187
    {
188
        $layout = $this->getLayout();
189
        if ($layout === 'horizontal') {
190
            $this->horizontalClientScriptInit();
191
        }
192
193
        return $this->render($layout);
194
    }
195
196
    private function horizontalClientScriptInit()
197
    {
198
        $view = $this->getView();
199
        $view->registerCss('
200
            .affix {
201
                top: 5px;
202
            }
203
            .affix-bottom {
204
                position: fixed!important;
205
            }
206
            @media (min-width: 768px) {
207
                .affix {
208
                    position: fixed;
209
                }
210
            }
211
            @media (max-width: 768px) {
212
                .affix {
213
                    position: static;
214
                }
215
            }
216
            .advanced-search[min-width~="150px"] form > div {
217
                width: 100%;
218
            }
219
            #scrollspy * {
220
              /* Свойства изменение которых необходимо отслеживать */
221
              transition-property: all;
222
223
              /* Устанавливаем "незаметную для глаза" длительность перехода */
224
              transition-duration: 1ms;
225
            }
226
        ');
227
        $view->registerJs("
228
            function affixInit() {
229
                $('#scrollspy').affix({
230
                    offset: {
231
                        top: ($('header.main-header').outerHeight(true) + $('section.content-header').outerHeight(true)) + 15,
232
                        bottom: ($('footer').outerHeight(true)) + 15
233
                    }
234
                });
235
            }
236
            $(document).on('pjax:end', function() {
237
                $('.advanced-search form > div').css({'width': '100%'});
238
                
239
                // Fix left search block position
240
                $(window).trigger('scroll');
241
            });
242
            if ($(window).height() > $('#scrollspy').outerHeight(true) && $(window).width() > 991) {
243
                if ( $('#scrollspy').outerHeight(true) < $('.horizontal-view .col-md-9 > .box').outerHeight(true) ) {
244
                    var fixAffixWidth = function() {
245
                        $('#scrollspy').each(function() {
246
                            $(this).width( $(this).parent().width() );
247
                        });
248
                    }
249
                    fixAffixWidth();
250
                    $(window).resize(fixAffixWidth);
251
                    affixInit();
252
                    $('a.sidebar-toggle').click(function() {
253
                        setTimeout(function(){
254
                            fixAffixWidth();
255
                        }, 500);
256
                    });
257
                }
258
            }
259
        ", View::POS_LOAD);
260
    }
261
262
    public function detectLayout()
263
    {
264
        return $this->getUiModel()->orientation;
265
    }
266
267
    /**
268
     * @param array $data
269
     * @void
270
     */
271
    public function setSearchFormData($data = [])
272
    {
273
        $this->searchFormData = $data;
274
    }
275
276
    /**
277
     * @param array $options
278
     * @void
279
     */
280
    public function setSearchFormOptions($options = [])
281
    {
282
        $this->searchFormOptions = $options;
283
    }
284
285
    public function renderSearchForm($advancedSearchOptions = [])
286
    {
287
        $advancedSearchOptions = array_merge($advancedSearchOptions, $this->searchFormOptions);
288
        ob_start();
289
        ob_implicit_flush(false);
290
        try {
291
            $search = $this->beginSearchForm($advancedSearchOptions);
292
            foreach (['per_page', 'representation'] as $key) {
293
                echo Html::hiddenInput($key, Yii::$app->request->get($key));
294
            }
295
            echo Yii::$app->view->render($this->searchView, array_merge(compact('search'), $this->searchFormData), $this->originalContext);
296
            $search->end();
297
        } catch (\Exception $e) {
298
            ob_end_clean();
299
            throw $e;
300
        }
301
302
        return ob_get_clean();
303
    }
304
305
    public function beginSearchForm($options = [])
306
    {
307
        return AdvancedSearch::begin(array_merge(['model' => $this->model], $options));
308
    }
309
310
    public function renderSearchButton()
311
    {
312
        return AdvancedSearch::renderButton() . "\n";
313
    }
314
315
    public function renderLayoutSwitcher()
316
    {
317
        return IndexLayoutSwitcher::widget(['uiModel' => $this->getUiModel()]);
318
    }
319
320
    public function renderPerPage()
321
    {
322
        $items = [];
323
        foreach ([25, 50, 100, 200, 500] as $pageSize) {
324
            $items[] = ['label' => $pageSize, 'url' => Url::current(['per_page' => $pageSize])];
325
        }
326
        return ButtonDropdown::widget([
327
            'label' => Yii::t('hipanel', 'Per page') . ': ' . $this->getUiModel()->per_page,
328
            'options' => ['class' => 'btn-default btn-sm'],
329
            'dropdown' => [
330
                'items' => $items,
331
            ],
332
        ]);
333
    }
334
335
    /**
336
     * Renders button to choose representation.
337
     * Returns empty string when nothing to choose (less then 2 representations available).
338
     * @param array $grid class
339
     * @param mixed $current selected representation
0 ignored issues
show
Bug introduced by
There is no parameter named $current. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
340
     * @return string rendered HTML
341
     */
342
    public function renderRepresentations($grid)
343
    {
344
        $current = $this->getUiModel()->representation;
345
        $representations = $grid::getRepresentations();
346
        if (count($representations) < 2) {
347
            return '';
348
        }
349
        if (!isset($representations[$current])) {
350
            $current = key($representations);
351
        }
352
        $items = [];
353
        foreach ($representations as $key => $data) {
354
            $items[] = [
355
                'label' => $data['label'],
356
                'url' => Url::current(['representation' => $key]),
357
            ];
358
        }
359
360
        return ButtonDropdown::widget([
361
            'label' => Yii::t('hipanel:synt', 'View') . ': ' . $representations[$current]['label'],
362
            'options' => ['class' => 'btn-default btn-sm'],
363
            'dropdown' => [
364
                'items' => $items,
365
            ],
366
        ]);
367
    }
368
369
    public function renderSorter(array $options)
370
    {
371
        return LinkSorter::widget(array_merge([
372
            'show' => true,
373
            'uiModel' => $this->getUiModel(),
374
            'dataProvider' => $this->dataProvider,
375
            'sort' => $this->dataProvider->getSort(),
376
            'buttonClass' => 'btn btn-default dropdown-toggle btn-sm',
377
        ], $options));
378
    }
379
380
    public function getViewPath()
381
    {
382
        return parent::getViewPath() . DIRECTORY_SEPARATOR . (new \ReflectionClass($this))->getShortName();
383
    }
384
385
    public function getBulkFormId()
386
    {
387
        return 'bulk-' . Inflector::camel2id($this->model->formName());
388
    }
389
390
    public function beginBulkForm($action = '')
391
    {
392
        echo Html::beginForm($action, 'POST', ['id' => $this->getBulkFormId()]);
393
    }
394
395
    public function endBulkForm()
396
    {
397
        echo Html::endForm();
398
    }
399
400 View Code Duplication
    public function renderBulkButton($text, $action, $color = 'default')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
401
    {
402
        return Html::submitButton($text, [
403
            'class' => "btn btn-$color btn-sm",
404
            'form' => $this->getBulkFormId(),
405
            'formmethod' => 'POST',
406
            'formaction' => $action,
407
        ]);
408
    }
409
410
    /**
411
     * @return string
412
     */
413
    public function getLayout()
414
    {
415
        if ($this->_layout === null) {
416
            $this->_layout = $this->detectLayout();
417
        }
418
        return $this->_layout;
419
    }
420
421
    /**
422
     * @param string $layout
423
     */
424
    public function setLayout($layout)
425
    {
426
        $this->_layout = $layout;
427
    }
428
}
429