ViewRenderBehavior   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 95.83%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 6
dl 0
loc 74
ccs 23
cts 24
cp 0.9583
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A events() 0 6 1
A beforeRender() 0 14 2
B getDir() 0 23 7
1
<?php
2
/**
3
 * @link https://github.com/vuongxuongminh/yii2-mobile-first
4
 * @copyright Copyright (c) 2019 Vuong Xuong Minh
5
 * @license [New BSD License](http://www.opensource.org/licenses/bsd-license.php)
6
 */
7
8
namespace vxm\mobileFirst;
9
10
use Yii;
11
12
use yii\base\Behavior;
13
use yii\base\ViewEvent;
14
use yii\web\View;
15
16
/**
17
 * Class ViewRenderBehavior support rendering view by device type.
18
 *
19
 * @author Vuong Minh <[email protected]>
20
 * @since 1.0.0
21
 */
22
class ViewRenderBehavior extends Behavior
23
{
24
    use DetectorTrait;
25
26
    /**
27
     * @var array have key's device type and value's directory name store all views of this device.
28
     * @see [[getDir()]]
29
     */
30
    public $dirMap = [
31
        'mobile' => 'mobile',
32
        'tablet' => 'tablet'
33
    ];
34
35
    /**
36
     * @inheritDoc
37
     */
38 6
    public function events()
39
    {
40
        return [
41 6
            View::EVENT_BEFORE_RENDER => 'beforeRender'
42
        ];
43
    }
44
45
    /**
46
     * An event handle when rendering view support render by device type.
47
     *
48
     * @param ViewEvent $event triggered.
49
     * @throws \yii\base\InvalidConfigException
50
     */
51 6
    public function beforeRender(ViewEvent $event)
52
    {
53 6
        if ($event->isValid) {
54
            /** @var View $view */
55 6
            $view = $event->sender;
56 6
            $ext = pathinfo($event->viewFile, PATHINFO_EXTENSION);
57 6
            $renderer = $view->renderers[$ext] ?? null;
58 6
            $view->renderers[$ext] = Yii::createObject([
59 6
                'class' => ViewRenderer::class,
60 6
                'dir' => $this->getDir(),
61 6
                'renderer' => $renderer
62
            ]);
63
        }
64 6
    }
65
66
    /**
67
     * Get dir by requested device.
68
     *
69
     * @return string|null dir store all views of device or null if not match all element in [[$dirMap]].
70
     * @throws \yii\base\InvalidConfigException
71
     */
72 6
    protected function getDir(): ?string
73
    {
74 6
        $detector = $this->getDetector();
75 6
        $dirMap = array_change_key_case($this->dirMap);
76
77 6
        foreach ($dirMap as $device => $dir) {
78
79 6
            if ($device === 'mobile') {
80 6
                $match = $detector->isMobile() && (!isset($dirMap['tablet']) || !$detector->isTablet());
81 4
            } elseif ($device === 'tablet') {
82 4
                $match = $detector->isTablet();
83
            } else {
84
                $match = $detector->is($device);
85
            }
86
87 6
            if ($match) {
88 4
                return $dir;
89
            }
90
91
        }
92
93 2
        return null;
94
    }
95
}
96