HitCounterWidget::initClientImgOptions()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 10
ccs 8
cts 8
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 * @copyright Copyright (C) 2019 Sergio coderius <coderius>
4
 * @license This program is free software: the MIT License (MIT)
5
 */
6
7
namespace coderius\hitCounter\widgets\hitCounter;
8
9
use Yii;
10
use coderius\hitCounter\Module;
11
use yii\base\Widget;
12
use yii\helpers\Json;
13
use yii\web\View;
14
use yii\web\JsExpression;
15
use yii\helpers\Html;
16
use yii\base\InvalidParamException;
17
use yii\helpers\Url;
18
use coderius\hitCounter\config\Enum;
19
20
/**
21
 * Widget.
22
 */
23
class HitCounterWidget extends Widget
24
{
25
    const COUNTER_VIEW_INVISIBLE = 'invisible';
26
27
    /**
28
     * Array with params which can be transferred by img src to controller.
29
     * Possible parameters:
30
     * - 'type'
31
     * - 'period'
32
     * 
33
     * Default params setted in init method:
34
     *  $counterOptions = [
35
     *      'type' => self::COUNTER_VIEW_INVISIBLE,
36
     *      'period' => Enum::PERIOD_DAY
37
     *  ];
38
     *
39
     * @var array
40
     */
41
    public $counterId;
42
43
    public $counterOptions = [];
44
45
    public $linkUrl;
46
47
    private $imgSrc;
48
49
    private $clientLinkOptions = [];
50
51
    /**
52
     * Relevant tag image attributes (style etc.)
53
     *
54
     * @var array
55
     */
56
    private $clientImgOptions = [];
57
58
    private $widgetId;
59
60
    private $counterName = "Hit counter";
61
62
    /**
63
     * Undocumented function
64
     *
65
     * @return array
66
     */
67 15
    protected static function counterViewTypes()
68
    {
69
        return [
70 15
            self::COUNTER_VIEW_INVISIBLE
71
        ];
72
    }
73
74
    /**
75
     * Return array with constants date period
76
     *
77
     * @return array
78
     */
79 12
    protected static function counterViewPeriod()
80
    {
81
        return [
82 12
            Enum::PERIOD_DAY,
83 12
            Enum::PERIOD_WEEK,
84 12
            Enum::PERIOD_MONTH,
85
        ];
86
    }
87
88 15
    public function init()
89
    {
90 15
        parent::init();
91
92 15
        if(null === $this->counterId){
93 9
            $this->counterId = $this->getId();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getId() of type string is incompatible with the declared type array of property $counterId.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
        }
95
96
        // Set defaults in src img (with params to be transferred to the controller)
97
        $defCOpts = [
98 15
            'type' => self::COUNTER_VIEW_INVISIBLE,
99 15
            'period' => Enum::PERIOD_DAY
100
        ];
101
102 15
        $this->counterOptions = array_merge($defCOpts, $this->counterOptions);
103
104
        //Сheck valid values of counter type
105 15
        if (!in_array($this->counterOptions['type'], self::counterViewTypes())) {
106 3
            throw new InvalidParamException("Unknown counter view type '{$this->counterOptions['type']}'.");
0 ignored issues
show
Deprecated Code introduced by
The class yii\base\InvalidParamException has been deprecated: since 2.0.14. Use [[InvalidArgumentException]] instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

106
            throw /** @scrutinizer ignore-deprecated */ new InvalidParamException("Unknown counter view type '{$this->counterOptions['type']}'.");
Loading history...
107
        }
108
109
        //Сheck valid values of counter view period in generated counter image
110 12
        if (!array_key_exists($this->counterOptions['period'], self::counterViewPeriod())) {
111 3
            throw new InvalidParamException("Unknown counter view period '{$this->counterOptions['period']}'.");
0 ignored issues
show
Deprecated Code introduced by
The class yii\base\InvalidParamException has been deprecated: since 2.0.14. Use [[InvalidArgumentException]] instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

111
            throw /** @scrutinizer ignore-deprecated */ new InvalidParamException("Unknown counter view period '{$this->counterOptions['period']}'.");
Loading history...
112
        }
113
        
114 9
        $this->imgSrc = Url::toRoute(['/hitCounter/hit-counter/index'], true);
115 9
        $this->widgetId = $this->getId();
116
        
117 9
        $this->initClientLinkOptions();
118 9
        $this->initClientImgOptions();
119 9
    }
120
121
    //?netbeanse-xdebug
122 6
    public function run()
123
    {
124 6
        parent::run();
125
126
        //Create counter by event hendler when trigger event in view component View::EVENT_END_PAGE
127 6
        Yii::debug('Starting make counter code in app view', __METHOD__);
128
        // $this->getView()->on(\yii\base\View::EVENT_END_PAGE, [$this, 'makeCounter']);
129 6
        return $this->makeCounter();
130
        Yii::debug('Ending make counter code in app view', __METHOD__);
0 ignored issues
show
Unused Code introduced by
Yii::debug('Ending make ... app view', __METHOD__) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
131
        
132
    }
133
134
    /**
135
     * Print counter code
136
     * 
137
     * @return string
138
     */
139 6
    protected function makeCounter()
140
    {
141 6
        $output = '';
142
143
        //Default counter set is invisible (self::COUNTER_VIEW_INVISIBLE)
144 6
        $type = $this->counterOptions['type'];
145
146
        //Since the attributes will be displayed inside javascript in view file, needed escape string
147 6
        $clientImgOptions = addslashes(Html::renderTagAttributes($this->clientImgOptions));
148
        
149
        //Render view file wich relevant counter type
150 6
        $output .= $this->render($type . "-counter.php", [
151 6
                'counterId' => $this->counterId,
152 6
                'imgSrc' => $this->imgSrc, 
153 6
                'clientImgOptions' => $clientImgOptions, //Style etc.
154 6
                'counterImgSrcQuery' => $this->counterOptionsToQueryStr()
155
            ]);
156
157 6
        $output .= $this->buildNoScriptHtml();
158
        
159
        //If isset wrapper link url, counter code put inside <a></a> tag
160
        //This may be necessary if the counter is visible and clickable so that you can go to the statistics page.
161 6
        $output = $this->linkUrl ? Html::a($output, $this->linkUrl, $this->clientLinkOptions) : $output;
162
163
        //Print html comments to counter output
164 6
        echo "<!-- {$this->counterName}-->" . $output . "<!-- / {$this->counterName} -->";
165 6
    }
166
167
    /**
168
     * Init image options relevant to counter type.
169
     *
170
     * @return void
171
     */
172 9
    protected function initClientImgOptions()
173
    {
174 9
        $this->clientImgOptions["alt"] = $this->counterName;
175
176 9
        switch ($this->counterOptions['type']) {
177 9
            case self::COUNTER_VIEW_INVISIBLE:
178 9
            $visOpts = ["style" => "width:1px; height:1px"];
179 9
            $visOpts["style"] .= $this->linkUrl ? "" : ";position:absolute; left:-9999px;";
180 9
            $this->clientImgOptions = array_merge($this->clientImgOptions, $visOpts);
181 9
                break;
182
        }
183 9
    }
184
185
    /**
186
     * Init wrap link options relevant to counter type.
187
     *
188
     * @return void
189
     */
190 9
    protected function initClientLinkOptions()
191
    {
192 9
        $defOpts = [];
193 9
        $defOpts['target'] = '_blank';
194 9
        if($this->counterOptions['type'] === self::COUNTER_VIEW_INVISIBLE) $defOpts['style'] = 'position:absolute; left:-9999px;';
195 9
        $this->clientLinkOptions = array_merge($defOpts, $this->clientLinkOptions);
196
197 9
    }
198
199
    /**
200
     * Return noscript tag with image tag
201
     *
202
     * @return string
203
     */
204 6
    protected function buildNoScriptHtml()
205
    {
206
        
207 6
        $tag = "noscript";
208 6
        $content = Html::img($this->imgSrc, $this->clientImgOptions);
209 6
        return Html::tag($tag, $content, []);
210
    }
211
212
    /**
213
     * Return query string for pass to src image params like period for generate count visits in hit counter image (if it most be an visible)
214
     *
215
     * @return string
216
     */
217 6
    protected function counterOptionsToQueryStr()
218
    {
219 6
        return http_build_query($this->counterOptions);
220
    }
221
222
}