PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.14.2
Independent Analytics – WordPress Analytics Plugin v2.14.2
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / IAWP / Admin_Page / Analytics_Page.php
independent-analytics / IAWP / Admin_Page Last commit date
Admin_Page.php 7 months ago Analytics_Page.php 7 months ago Campaign_Builder_Page.php 2 years ago Click_Tracking_Page.php 1 year ago Debug_Page.php 1 year ago Integrations_Pages.php 1 year ago Settings_Page.php 2 years ago Support_Page.php 1 year ago Updates_Page.php 1 year ago Visitor_Page.php 6 months ago
Analytics_Page.php
320 lines
1 <?php
2
3 namespace IAWP\Admin_Page;
4
5 use IAWP\Capability_Manager;
6 use IAWP\Chart;
7 use IAWP\Dashboard_Options;
8 use IAWP\Database;
9 use IAWP\Env;
10 use IAWP\Examiner\Header;
11 use IAWP\Map;
12 use IAWP\Map_Data;
13 use IAWP\Overview\Overview;
14 use IAWP\Plugin_Conflict_Detector;
15 use IAWP\Quick_Stats;
16 use IAWP\Real_Time;
17 use IAWP\Report;
18 use IAWP\Report_Finder;
19 use IAWP\Tables\Table;
20 use IAWP\Tables\Table_Journeys;
21 use IAWP\Utils\Request;
22 use IAWP\Utils\Security;
23 use IAWPSCOPED\Illuminate\Support\Arr;
24 use IAWPSCOPED\Illuminate\Support\Collection;
25 /** @internal */
26 class Analytics_Page extends \IAWP\Admin_Page\Admin_Page
27 {
28 protected function render_page()
29 {
30 $options = Dashboard_Options::getInstance();
31 $date_rage = $options->get_date_range();
32 $tab = (new Env())->get_tab();
33 $report = Report_Finder::new()->fetch_current_report();
34 $is_showing_skeleton_ui = $report instanceof Report && $report->has_filters();
35 // Real-time is its own thing
36 if ($tab === 'real-time') {
37 $real_time = new Real_Time();
38 $real_time->render_real_time_analytics();
39 return;
40 }
41 // Overview is its own thing
42 if ($tab === 'overview') {
43 $overview = new Overview();
44 echo $overview->get_report_html();
45 $this->notices();
46 return;
47 }
48 // User journeys is a very difference animal
49 if ($tab === 'journeys') {
50 $this->user_journey_interface();
51 return;
52 }
53 $table_class = Env::get_table($tab);
54 $table = new $table_class($options->group());
55 $sort_configuration = $table->sanitize_sort_parameters($options->sort_column(), $options->sort_direction());
56 $hide_unfiltered_statistics = \false;
57 $rows = null;
58 $examiner_model = null;
59 if ($options->is_examiner()) {
60 $rows_class = $table->group()->rows_class();
61 $rows = new $rows_class($options->get_date_range(), $sort_configuration);
62 $id = Request::query_int('examiner');
63 $rows->limit_to($id);
64 $examiner_model = $rows->rows()[0];
65 $hide_unfiltered_statistics = \true;
66 }
67 $statistics_class = $table->group()->statistics_class();
68 $statistics = new $statistics_class($date_rage, $rows, $options->chart_interval());
69 $stats = new Quick_Stats($statistics, \false, $is_showing_skeleton_ui, $hide_unfiltered_statistics);
70 // Never show the map when loading the geo examiner. It'll only ever show a single country anyway.
71 if ($tab === 'geo' && !$options->is_examiner()) {
72 $table_data_class = $table->group()->rows_class();
73 $geo_data = new $table_data_class($date_rage, $table->sanitize_sort_parameters());
74 $map_data = new Map_Data($geo_data->rows());
75 $chart = new Map($map_data->get_country_data(), null, $is_showing_skeleton_ui);
76 } else {
77 $chart = new Chart($statistics, \false, $is_showing_skeleton_ui);
78 }
79 $this->interface($table, $stats, $chart, $examiner_model);
80 }
81 private function user_journey_interface()
82 {
83 $options = Dashboard_Options::getInstance();
84 $table = new Table_Journeys();
85 $sort_configuration = $table->sanitize_sort_parameters('created_at', 'DESC');
86 $header = \IAWPSCOPED\iawp_blade()->run('partials.report-header', ['report' => Report_Finder::new()->fetch_current_report(), 'can_edit' => Capability_Manager::can_edit()]);
87 ?>
88 <div data-controller="report"
89 data-report-is-examiner-value="<?php
90 echo $options->is_examiner() ? '1' : '0';
91 ?>"
92 data-report-name-value="<?php
93 echo Security::string($options->report_name());
94 ?>"
95 data-report-report-name-value="<?php
96 echo Security::string($table->group()->singular());
97 ?>"
98 data-report-relative-range-id-value="<?php
99 echo Security::attr($options->relative_range_id());
100 ?>"
101 data-report-exact-start-value="<?php
102 echo Security::attr($options->start());
103 ?>"
104 data-report-exact-end-value="<?php
105 echo Security::attr($options->end());
106 ?>"
107 data-report-group-value="<?php
108 echo Security::attr($table->group()->id());
109 ?>"
110 data-report-filters-value="<?php
111 echo \esc_attr(Security::json_encode($options->raw_filters()));
112 ?>"
113 data-report-filter-logic-value="<?php
114 echo Security::attr($options->filter_logic());
115 ?>"
116 data-report-chart-interval-value="<?php
117 echo Security::attr($options->chart_interval()->id());
118 ?>"
119 data-report-sort-column-value="<?php
120 echo Security::attr($sort_configuration->column());
121 ?>"
122 data-report-sort-direction-value="<?php
123 echo Security::attr($sort_configuration->direction());
124 ?>"
125 data-report-columns-value="<?php
126 echo \esc_attr(Security::json_encode($table->visible_column_ids()));
127 ?>"
128 data-report-quick-stats-value="<?php
129 echo \esc_attr(Security::json_encode($options->visible_quick_stats()));
130 ?>"
131 data-report-primary-chart-metric-id-value="<?php
132 echo \esc_attr($options->primary_chart_metric_id());
133 ?>"
134 data-report-secondary-chart-metric-id-value="<?php
135 echo \esc_attr($options->secondary_chart_metric_id());
136 ?>"
137 >
138 <div id="report-header-container" class="report-header-container">
139 <?php
140 echo $header;
141 ?>
142 <?php
143 $table->output_report_toolbar();
144 ?>
145 <div class="modal-background"></div>
146 </div>
147 <?php
148 echo $table->get_table_toolbar_markup();
149 ?>
150 <div class="user-journeys">
151 <?php
152 echo $table->get_table_markup($sort_configuration->column(), $sort_configuration->direction());
153 ?>
154 </div>
155 </div>
156 <?php
157 $this->notices();
158 }
159 private function interface(Table $table, $stats, $chart, $examiner_model = null)
160 {
161 $options = Dashboard_Options::getInstance();
162 $sort_configuration = $table->sanitize_sort_parameters($options->sort_column(), $options->sort_direction());
163 $header = \IAWPSCOPED\iawp_blade()->run('partials.report-header', ['report' => Report_Finder::new()->fetch_current_report(), 'can_edit' => Capability_Manager::can_edit()]);
164 $examiner_tabs = '';
165 if ($examiner_model) {
166 $header = Header::html($table, $examiner_model);
167 $available_tabs = Collection::make($this->examiner_tabs())->filter(function (array $table) use($examiner_model) {
168 return $table['table_type'] !== $examiner_model->table_type();
169 })->values()->all();
170 $current = Arr::first($available_tabs);
171 $examiner_tabs = \IAWPSCOPED\iawp_blade()->run('examiner.table-tabs', ['tables' => $available_tabs, 'active' => $current['table_type']]);
172 $table_class = Env::get_table($current['table_type']);
173 $table = new $table_class();
174 }
175 ?>
176 <div data-controller="report"
177 data-report-is-examiner-value="<?php
178 echo $options->is_examiner() ? '1' : '0';
179 ?>"
180 data-report-name-value="<?php
181 echo Security::string($options->report_name());
182 ?>"
183 data-report-report-name-value="<?php
184 echo Security::string($table->group()->singular());
185 ?>"
186 data-report-relative-range-id-value="<?php
187 echo Security::attr($options->relative_range_id());
188 ?>"
189 data-report-exact-start-value="<?php
190 echo Security::attr($options->start());
191 ?>"
192 data-report-exact-end-value="<?php
193 echo Security::attr($options->end());
194 ?>"
195 data-report-group-value="<?php
196 echo Security::attr($table->group()->id());
197 ?>"
198 data-report-filters-value="<?php
199 echo \esc_attr(Security::json_encode($options->raw_filters()));
200 ?>"
201 data-report-filter-logic-value="<?php
202 echo Security::attr($options->filter_logic());
203 ?>"
204 data-report-chart-interval-value="<?php
205 echo Security::attr($options->chart_interval()->id());
206 ?>"
207 data-report-sort-column-value="<?php
208 echo Security::attr($sort_configuration->column());
209 ?>"
210 data-report-sort-direction-value="<?php
211 echo Security::attr($sort_configuration->direction());
212 ?>"
213 data-report-columns-value="<?php
214 echo \esc_attr(Security::json_encode($table->visible_column_ids()));
215 ?>"
216 data-report-quick-stats-value="<?php
217 echo \esc_attr(Security::json_encode($options->visible_quick_stats()));
218 ?>"
219 data-report-primary-chart-metric-id-value="<?php
220 echo \esc_attr($options->primary_chart_metric_id());
221 ?>"
222 data-report-secondary-chart-metric-id-value="<?php
223 echo \esc_attr($options->secondary_chart_metric_id());
224 ?>"
225 >
226 <div id="report-header-container" class="report-header-container">
227 <?php
228 echo $header;
229 ?>
230 <?php
231 $table->output_report_toolbar();
232 ?>
233 <div class="modal-background"></div>
234 </div>
235 <?php
236 echo $stats->get_html();
237 ?>
238 <?php
239 echo $chart->get_html();
240 ?>
241 <?php
242 echo $examiner_tabs;
243 ?>
244 <?php
245 echo $table->get_table_toolbar_markup();
246 ?>
247 <?php
248 echo $table->get_table_markup($sort_configuration->column(), $sort_configuration->direction());
249 ?>
250 </div>
251 <?php
252 if (!$options->is_examiner()) {
253 ?>
254 <div id="iawp-examiner-modal" aria-hidden="true" class="mm micromodal-slide" data-controller="examiner">
255 <div tabindex="-1" class="mm__overlay mm__overlay--full-screen" data-action="click->examiner#close:self" >
256 <div role="dialog" aria-modal="true" class="mm__container examiner examiner--loading">
257 <div data-examiner-target="content" class="examiner-content"></div>
258 <?php
259 echo \IAWPSCOPED\iawp_blade()->run('examiner.skeleton');
260 ?>
261 </div>
262 </div>
263 </div>
264 <?php
265 }
266 ?>
267 <?php
268 if (Env::get_tab() === 'geo') {
269 echo '<div class="geo-ip-attribution">';
270 echo \esc_html_x('Geolocation data powered by', 'Following text is a noun: DB-IP', 'independent-analytics') . ' ' . '<a href="https://db-ip.com" target="_blank">DB-IP</a>.';
271 echo '</div>';
272 }
273 $this->notices();
274 }
275 private function notices()
276 {
277 $plugin_conflict_detector = new Plugin_Conflict_Detector();
278 $requires_logged_in_tracking = $plugin_conflict_detector->plugin_requiring_logged_in_tracking();
279 $show_logged_in_tracking_notice = $requires_logged_in_tracking && !\get_option('iawp_track_authenticated_users') && !\get_option('iawp_need_clear_cache') && !\get_option('iawp_logged_in_tracking_notice');
280 ?><div class="iawp-notices"><?php
281 if (Capability_Manager::can_edit()) {
282 if ($plugin_conflict_detector->has_conflict()) {
283 echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => $plugin_conflict_detector->get_error(), 'button_text' => \false, 'id' => 'plugin-conflict', 'notice' => 'iawp-error', 'plugin' => $plugin_conflict_detector->get_plugin(), 'url' => 'https://independentwp.com/knowledgebase/tracking/secure-rest-api/']);
284 } elseif (\IAWPSCOPED\iawp_is_pro() && \is_plugin_active('better-wp-security/better-wp-security.php')) {
285 $settings = \get_option('itsec-storage');
286 if (\array_key_exists('system-tweaks', $settings)) {
287 if (\array_key_exists('plugins_php', $settings['system-tweaks'])) {
288 if ($settings['system-tweaks']['plugins_php']) {
289 echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('The "Solid Security" plugin is disabling PHP execution in the plugins folder, and this is preventing click tracking from working. Please visit the Security > Settings page, click on the Advanced section, click on System Tweaks Settings, uncheck the "Disable PHP Plugins" option, and then save.', 'independent-analytics'), 'button_text' => \false, 'id' => 'plugin-conflict', 'notice' => 'iawp-error', 'url' => 'https://independentwp.com/knowledgebase/click-tracking/allow-php-execution-plugins-folder/']);
290 }
291 }
292 }
293 }
294 if (\get_option('iawp_need_clear_cache')) {
295 echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('Please clear your cache to ensure tracking works properly.', 'independent-analytics'), 'button_text' => \__('I\'ve cleared the cache', 'independent-analytics'), 'id' => 'iawp_need_clear_cache', 'notice' => 'iawp-warning', 'url' => 'https://independentwp.com/knowledgebase/common-questions/views-not-recording/']);
296 }
297 if ($show_logged_in_tracking_notice) {
298 echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => '<strong>' . \sprintf(\_x('%s compatibility:', 'Variable is the name of a plugin', 'independent-analytics'), $requires_logged_in_tracking) . '</strong> ' . \__('We recommend you enable tracking for logged-in visitors.', 'independent-analytics'), 'button_text' => \__('Dismiss', 'independent-analytics'), 'id' => 'enable-logged-in-tracking', 'notice' => 'iawp-warning', 'url' => 'https://independentwp.com/knowledgebase/tracking/how-to-track-logged-in-visitors/']);
299 }
300 if (\IAWPSCOPED\iawp_db_version() > 0 && !Database::has_correct_database_privileges()) {
301 echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('Your site is missing the following critical database permissions:', 'independent-analytics') . ' ' . \implode(', ', Database::missing_database_privileges()) . '. ' . \__('There is no issue at this time, but you will need to enable the missing permissions before updating the plugin to a newer version to ensure an error is avoided. Please click this link to read our tutorial:', 'independent-analytics'), 'button_text' => \false, 'id' => 'missing-permissions', 'notice' => 'iawp-error', 'url' => 'https://independentwp.com/knowledgebase/common-questions/missing-database-permissions/']);
302 }
303 if (Env::get_tab() === 'clicks') {
304 if (!\get_option('iawp_clicks_sync_notice')) {
305 echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('Click data syncs every 60 seconds. Please allow for this delay when testing clicks on new links.', 'independent-analytics'), 'button_text' => \__('Dismiss', 'independent-analytics'), 'id' => 'iawp_clicks_sync_notice', 'notice' => 'iawp-warning', 'url' => 'https://independentwp.com/knowledgebase/click-tracking/click-tracking-update-process/']);
306 }
307 }
308 }
309 ?>
310 </div><?php
311 if (\get_option('iawp_show_gsg') === '1' && !\get_option('iawp_need_clear_cache') && !$show_logged_in_tracking_notice && !$plugin_conflict_detector->has_conflict() && (Env::get_tab() !== 'clicks' || Env::get_tab() === 'clicks' && \get_option('iawp_clicks_sync_notice'))) {
312 echo \IAWPSCOPED\iawp_blade()->run('notices.getting-started');
313 }
314 }
315 private function examiner_tabs() : array
316 {
317 return [['table_type' => 'views', 'name' => \__('Pages', 'independent-analytics')], ['table_type' => 'referrers', 'name' => \__('Referrers', 'independent-analytics')], ['table_type' => 'geo', 'name' => \__('Geographic', 'independent-analytics')], ['table_type' => 'devices', 'name' => \__('Devices', 'independent-analytics')], ['table_type' => 'campaigns', 'name' => \__('Campaigns', 'independent-analytics')], ['table_type' => 'clicks', 'name' => \__('Clicks', 'independent-analytics')]];
318 }
319 }
320