Issues (127)

src/widgets/Report.php (2 issues)

1
<?php
2
/**
3
 * @link      https://dukt.net/analytics/
4
 * @copyright Copyright (c) 2022, Dukt
5
 * @license   https://github.com/dukt/analytics/blob/master/LICENSE.md
6
 */
7
8
namespace dukt\analytics\widgets;
9
10
use Craft;
11
use craft\helpers\Json;
12
use craft\helpers\StringHelper;
13
use dukt\analytics\web\assets\reportwidget\ReportWidgetAsset;
14
use dukt\analytics\Plugin as Analytics;
15
use craft\web\View;
16
17
class Report extends \craft\base\Widget
18
{
19
    // Properties
20
    // =========================================================================
21
22
    /**
23
     * @var string|null
24
     */
25
    public $viewId;
26
27
    /**
28
     * @var bool|null
29
     */
30
    public $realtime;
31
32
    /**
33
     * @var string|null
34
     */
35
    public $chart;
36
37
    /**
38
     * @var string|null
39
     */
40
    public $period;
41
42
    /**
43
     * @var array|null
44
     */
45
    public $options;
46
47
    // Public Methods
48
    // =========================================================================
49
50
    /**
51
     * @inheritdoc
52
     */
53
    public static function displayName(): string
54
    {
55
        return Craft::t('analytics', 'Analytics Report');
56
    }
57
58
    /**
59
     * @inheritDoc IWidget::getTitle()
60
     *
61
     * @return string
62
     */
63
    public function getTitle(): string
64
    {
65
        $reportTitle = $this->_getReportTitle();
66
67
        if ($reportTitle) {
68
            return $reportTitle;
69
        }
70
71
        return Craft::t('analytics', 'Analytics Report');
72
    }
73
74
    /**
75
     * @inheritdoc
76
     */
77
    public static function icon()
78
    {
79
        return Craft::getAlias('@dukt/analytics/icons/report.svg');
0 ignored issues
show
Bug Best Practice introduced by
The expression return Craft::getAlias('...tics/icons/report.svg') also could return the type false which is incompatible with the return type mandated by craft\base\WidgetInterface::icon() of null|string.
Loading history...
80
    }
81
82
    /**
83
     * @inheritDoc IWidget::getBodyHtml()
84
     *
85
     * @return string|false
86
     * @throws \Twig_Error_Loader
87
     * @throws \yii\base\Exception
88
     */
89
    public function getBodyHtml()
90
    {
91
        $view = Craft::$app->getView();
92
93
        try {
94
            if (!Analytics::$plugin->getAnalytics()->checkPluginRequirements()) {
95
                return $view->renderTemplate('analytics/_special/not-connected');
96
            }
97
98
            if (!Analytics::$plugin->getSettings()->enableWidgets) {
99
                return $view->renderTemplate('analytics/_components/widgets/Report/disabled');
100
            }
101
102
            $reportingViews = Analytics::$plugin->getViews()->getViews();
103
104
            if (\count($reportingViews) === 0) {
105
                return $view->renderTemplate('analytics/_special/no-views');
106
            }
107
108
            $widgetSettings = $this->settings;
109
110
            $reportingView = Analytics::$plugin->getViews()->getViewById($widgetSettings['viewId']);
111
112
            if (!$reportingView) {
0 ignored issues
show
$reportingView is of type dukt\analytics\models\View, thus it always evaluated to true.
Loading history...
113
                return $view->renderTemplate('analytics/_special/view-not-configured');
114
            }
115
116
            $request = [
117
                'viewId' => $widgetSettings['viewId'] ?? null,
118
                'chart' => $widgetSettings['chart'] ?? null,
119
                'period' => $widgetSettings['period'] ?? null,
120
                'options' => $widgetSettings['options'][$widgetSettings['chart']] ?? null,
121
            ];
122
123
124
            // use cached response if available
125
126
            if (Analytics::$plugin->getSettings()->enableCache === true) {
127
                $cacheId = ['getReport', $request];
128
                $cachedResponse = Analytics::$plugin->cache->get($cacheId);
129
            }
130
131
132
            // render
133
            $jsOptions = [
134
                'currencyDefinition' => Analytics::$plugin->getAnalytics()->getCurrencyDefinition($reportingView->gaViewCurrency),
135
                'chartLanguage' => Analytics::$plugin->getAnalytics()->getChartLanguage(),
136
                'request' => $request,
137
                'cachedResponse' => $cachedResponse ?? null,
138
            ];
139
140
            $view->registerAssetBundle(ReportWidgetAsset::class);
141
142
            $view->registerJs('new Analytics.ReportWidget("widget'.$this->id.'", '.Json::encode($jsOptions).');');
143
144
            return $view->renderTemplate('analytics/_components/widgets/Report/body');
145
        } catch (\Exception $e) {
146
            Craft::error('Couldn’t load report widget: '.$e->getMessage(). " ".$e->getTraceAsString(), __METHOD__);
147
            return $view->renderTemplate('analytics/_special/error');
148
        }
149
    }
150
151
    /**
152
     * ISavableComponentType::getSettingsHtml()
153
     *
154
     * @return null|string
155
     * @throws \Twig_Error_Loader
156
     * @throws \yii\base\Exception
157
     * @throws \yii\base\InvalidConfigException
158
     */
159
    public function getSettingsHtml()
160
    {
161
        Craft::$app->getView()->registerAssetBundle(ReportWidgetAsset::class);
162
163
        $reportingViews = Analytics::$plugin->getViews()->getViews();
164
165
        if (\count($reportingViews) > 0) {
166
            $id = 'analytics-settings-'.StringHelper::randomString();
167
            $namespaceId = Craft::$app->getView()->namespaceInputId($id);
168
169
            Craft::$app->getView()->registerJs("new Analytics.ReportWidgetSettings('".$namespaceId."');");
170
171
            $chartTypes = ['area', 'counter', 'pie', 'table', 'geo'];
172
            $selectOptions = [];
173
174
            foreach ($chartTypes as $chartType) {
175
                $selectOptions[$chartType] = $this->_geSelectOptionsByChartType($chartType);
176
            }
177
178
            $settings = $this->getSettings();
179
180
            return Craft::$app->getView()->renderTemplate('analytics/_components/widgets/Report/settings', [
181
                'id' => $id,
182
                'settings' => $settings,
183
                'selectOptions' => $selectOptions,
184
                'reportingViews' => $reportingViews,
185
            ]);
186
        }
187
188
        return null;
189
    }
190
191
    // Private Methods
192
    // =========================================================================
193
194
    /**
195
     * Returns the dimension & metrics options for a given chart type
196
     *
197
     * @param $chartType
198
     *
199
     * @return array
200
     */
201
    private function _geSelectOptionsByChartType($chartType)
202
    {
203
        switch ($chartType) {
204
            case 'area':
205
206
                $options = [
207
                    'metrics' => Analytics::$plugin->metadata->getSelectMetricOptions()
208
                ];
209
210
                break;
211
212
            case 'counter':
213
214
                $options = [
215
                    'metrics' => Analytics::$plugin->metadata->getSelectMetricOptions()
216
                ];
217
218
                break;
219
220
            case 'geo':
221
222
                $options = [
223
                    'dimensions' => Analytics::$plugin->metadata->getSelectDimensionOptions(['ga:city', 'ga:country', 'ga:continent', 'ga:subContinent']),
224
                    'metrics' => Analytics::$plugin->metadata->getSelectMetricOptions()
225
                ];
226
227
                break;
228
229
            default:
230
231
                $options = [
232
                    'dimensions' => Analytics::$plugin->metadata->getSelectDimensionOptions(),
233
                    'metrics' => Analytics::$plugin->metadata->getSelectMetricOptions()
234
                ];
235
        }
236
237
        return $options;
238
    }
239
240
    /**
241
     * Returns the title of the report
242
     *
243
     * @return string|null
244
     */
245
    private function _getReportTitle()
246
    {
247
        try {
248
            $name = [];
249
            $chartType = $this->settings['chart'];
250
251
            if (isset($this->settings['options'][$chartType])) {
252
                $options = $this->settings['options'][$chartType];
253
254
                if (!empty($options['dimension'])) {
255
                    $name[] = Craft::t('analytics', Analytics::$plugin->metadata->getDimMet($options['dimension']));
256
                }
257
258
                if (!empty($options['metric'])) {
259
                    $name[] = Craft::t('analytics', Analytics::$plugin->metadata->getDimMet($options['metric']));
260
                }
261
            }
262
263
            if (!empty($this->settings['period'])) {
264
                $name[] = Craft::t('analytics', ucfirst($this->settings['period']));
265
            }
266
267
            if (count($name) > 0) {
268
                return implode(' - ', $name);
269
            }
270
        } catch (\Exception $e) {
271
            Craft::info('Couldn’t get Analytics Report’s title: '.$e->getMessage(), __METHOD__);
272
        }
273
274
        return null;
275
    }
276
}
277