PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.12.2
Independent Analytics – WordPress Analytics Plugin v2.12.2
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 / Rows / Device_Types.php
independent-analytics / IAWP / Rows Last commit date
Campaigns.php 10 months ago Cities.php 10 months ago Countries.php 10 months ago Device_Browsers.php 10 months ago Device_OSS.php 10 months ago Device_Types.php 10 months ago Filter.php 1 year ago Forms.php 10 months ago Link_Patterns.php 10 months ago Links.php 10 months ago Pages.php 10 months ago Referrers.php 10 months ago Rows.php 11 months ago
Device_Types.php
108 lines
1 <?php
2
3 namespace IAWP\Rows;
4
5 use IAWP\Form_Submissions\Form;
6 use IAWP\Illuminate_Builder;
7 use IAWP\Models\Device;
8 use IAWP\Query;
9 use IAWP\Query_Taps;
10 use IAWP\Tables;
11 use IAWPSCOPED\Illuminate\Database\Query\Builder;
12 use IAWPSCOPED\Illuminate\Database\Query\JoinClause;
13 /** @internal */
14 class Device_Types extends \IAWP\Rows\Rows
15 {
16 public function attach_filters(Builder $query) : void
17 {
18 $query->joinSub($this->query(\true), 'device_type_rows', function (JoinClause $join) {
19 $join->on('device_type_rows.device_type_id', '=', 'sessions.device_type_id');
20 });
21 }
22 protected function fetch_rows() : array
23 {
24 $rows = $this->query()->get()->all();
25 return \array_map(function ($row) {
26 return new Device($row);
27 }, $rows);
28 }
29 private function query(?bool $skip_pagination = \false) : Builder
30 {
31 if ($skip_pagination) {
32 $this->number_of_rows = null;
33 }
34 $views_table = Query::get_table_name(Query::VIEWS);
35 $sessions_table = Query::get_table_name(Query::SESSIONS);
36 $orders_table = Query::get_table_name(Query::ORDERS);
37 $device_types_table = Query::get_table_name(Query::DEVICE_TYPES);
38 $session_statistics = Illuminate_Builder::new();
39 $session_statistics->select('sessions.*')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('COUNT(DISTINCT orders.order_id) AS wc_orders')->selectRaw('IFNULL(CAST(SUM(orders.total) AS SIGNED), 0) AS wc_gross_sales')->selectRaw('IFNULL(CAST(SUM(orders.total_refunded) AS SIGNED), 0) AS wc_refunded_amount')->selectRaw('IFNULL(CAST(SUM(orders.total_refunds) AS SIGNED), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) {
40 foreach (Form::get_forms() as $form) {
41 $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]);
42 }
43 })->from("{$sessions_table} AS sessions")->join("{$views_table} AS views", function (JoinClause $join) {
44 $join->on('sessions.session_id', '=', 'views.session_id');
45 })->leftJoin("{$orders_table} AS orders", function (JoinClause $join) {
46 $join->on('views.id', '=', 'orders.initial_view_id')->where('orders.is_included_in_analytics', '=', \true);
47 })->leftJoin("{$this->tables::clicks()} AS clicks", function (JoinClause $join) {
48 $join->on('views.id', '=', 'clicks.view_id');
49 })->tap(Query_Taps::tap_authored_content_check())->when($this->examiner_config, function (Builder $query) {
50 if ($this->examiner_config->group() !== 'link_pattern') {
51 return;
52 }
53 $query->leftJoin(Tables::clicked_links() . ' AS clicked_links', function (JoinClause $join) {
54 $join->on('clicked_links.click_id', '=', 'clicks.click_id');
55 });
56 })->tap(Query_Taps::tap_related_to_examined_record($this->examiner_config))->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) {
57 $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range());
58 })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) {
59 $join->on('form_submissions.view_id', '=', 'views.id');
60 })->whereNotNull('sessions.device_type_id')->groupBy('sessions.session_id');
61 $device_types_query = Illuminate_Builder::new();
62 $device_types_query->select('device_types.device_type_id', 'device_types.device_type')->selectRaw('IFNULL(CAST(SUM(sessions.views) AS SIGNED), 0) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('SUM(sessions.clicks) AS clicks')->selectRaw('SUM(sessions.wc_orders) AS wc_orders')->selectRaw('SUM(sessions.wc_gross_sales) AS wc_gross_sales')->selectRaw('SUM(sessions.wc_refunded_amount) AS wc_refunded_amount')->selectRaw('SUM(sessions.wc_refunds) AS wc_refunds')->selectRaw('SUM(sessions.form_submissions) AS form_submissions')->tap(function (Builder $query) {
63 foreach (Form::get_forms() as $form) {
64 $query->selectRaw("SUM(sessions.{$form->submissions_column()}) AS {$form->submissions_column()}");
65 }
66 })->fromSub($session_statistics, 'sessions')->join($device_types_query->raw($device_types_table . ' AS device_types'), function (JoinClause $join) {
67 $join->on('sessions.device_type_id', '=', 'device_types.device_type_id');
68 })->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) {
69 $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range());
70 })->when(\count($this->filters) > 0, function (Builder $query) {
71 foreach ($this->filters as $filter) {
72 if (!$this->is_a_calculated_column($filter->column())) {
73 $filter->apply_to_query($query);
74 }
75 }
76 })->when(\is_int($this->solo_record_id), function (Builder $query) {
77 $query->where('device_types.device_type_id', '=', $this->solo_record_id);
78 })->groupBy('device_types.device_type_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) {
79 $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) {
80 $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END");
81 })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('device_type')->when(\is_int($this->number_of_rows), function (Builder $query) {
82 $query->limit($this->number_of_rows);
83 });
84 });
85 $previous_period_query = Illuminate_Builder::new();
86 $previous_period_query->select(['sessions.device_type_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.device_type_id');
87 $outer_query = Illuminate_Builder::new();
88 $outer_query->selectRaw('device_types.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) {
89 foreach (Form::get_forms() as $form) {
90 $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}");
91 }
92 })->when(\count($this->filters) > 0, function (Builder $query) {
93 foreach ($this->filters as $filter) {
94 if ($this->is_a_calculated_column($filter->column())) {
95 $filter->apply_to_query($query);
96 }
97 }
98 })->fromSub($device_types_query, 'device_types')->leftJoinSub($previous_period_query, 'previous_period_stats', 'device_types.device_type_id', '=', 'previous_period_stats.device_type_id')->when($this->is_using_a_calculated_column(), function (Builder $query) {
99 $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) {
100 $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END");
101 })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('device_type')->when(\is_int($this->number_of_rows), function (Builder $query) {
102 $query->limit($this->number_of_rows);
103 });
104 });
105 return $outer_query;
106 }
107 }
108