Campaigns.php
1 year ago
Cities.php
1 year ago
Countries.php
1 year ago
Device_Browsers.php
1 year ago
Device_OSS.php
1 year ago
Device_Types.php
1 year ago
Filter.php
1 year ago
Pages.php
1 year ago
Referrers.php
1 year ago
Rows.php
1 year ago
Device_OSS.php
91 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 IAWPSCOPED\Illuminate\Database\Query\Builder; |
| 11 | use IAWPSCOPED\Illuminate\Database\Query\JoinClause; |
| 12 | /** @internal */ |
| 13 | class Device_OSS extends \IAWP\Rows\Rows |
| 14 | { |
| 15 | public function attach_filters(Builder $query) : void |
| 16 | { |
| 17 | $query->joinSub($this->query(\true), 'device_os_rows', function (JoinClause $join) { |
| 18 | $join->on('device_os_rows.device_os_id', '=', 'sessions.device_os_id'); |
| 19 | }); |
| 20 | } |
| 21 | protected function fetch_rows() : array |
| 22 | { |
| 23 | $rows = $this->query()->get()->all(); |
| 24 | return \array_map(function ($row) { |
| 25 | return new Device($row); |
| 26 | }, $rows); |
| 27 | } |
| 28 | private function query(?bool $skip_pagination = \false) : Builder |
| 29 | { |
| 30 | if ($skip_pagination) { |
| 31 | $this->number_of_rows = null; |
| 32 | } |
| 33 | $views_table = Query::get_table_name(Query::VIEWS); |
| 34 | $sessions_table = Query::get_table_name(Query::SESSIONS); |
| 35 | $orders_table = Query::get_table_name(Query::ORDERS); |
| 36 | $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); |
| 37 | $orders_query = Illuminate_Builder::get_builder(); |
| 38 | $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS UNSIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS UNSIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); |
| 39 | $device_oss_query = Illuminate_Builder::get_builder(); |
| 40 | $device_oss_query->select('device_oss.device_os_id', 'device_oss.device_os AS os')->selectRaw('COUNT(DISTINCT views.id) 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('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { |
| 41 | foreach (Form::get_forms() as $form) { |
| 42 | $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); |
| 43 | } |
| 44 | })->from($views_table, 'views')->leftJoin($device_oss_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { |
| 45 | $join->on('views.session_id', '=', 'sessions.session_id'); |
| 46 | })->join($device_oss_query->raw($device_oss_table . ' AS device_oss'), function (JoinClause $join) { |
| 47 | $join->on('sessions.device_os_id', '=', 'device_oss.device_os_id'); |
| 48 | })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { |
| 49 | $join->on('the_orders.view_id', '=', 'views.id'); |
| 50 | })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { |
| 51 | $join->on('form_submissions.view_id', '=', 'views.id'); |
| 52 | })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { |
| 53 | $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); |
| 54 | })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { |
| 55 | foreach ($this->filters as $filter) { |
| 56 | if (!$this->is_a_calculated_column($filter->column())) { |
| 57 | $filter->apply_to_query($query); |
| 58 | } |
| 59 | } |
| 60 | })->groupBy('device_oss.device_os_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { |
| 61 | $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { |
| 62 | $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); |
| 63 | })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('os')->when(\is_int($this->number_of_rows), function (Builder $query) { |
| 64 | $query->limit($this->number_of_rows); |
| 65 | }); |
| 66 | }); |
| 67 | $previous_period_query = Illuminate_Builder::get_builder(); |
| 68 | $previous_period_query->select(['sessions.device_os_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_os_id'); |
| 69 | $outer_query = Illuminate_Builder::get_builder(); |
| 70 | $outer_query->selectRaw('device_oss.*')->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 UNSIGNED)) 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 UNSIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { |
| 71 | foreach (Form::get_forms() as $form) { |
| 72 | $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); |
| 73 | } |
| 74 | })->when(\count($this->filters) > 0, function (Builder $query) { |
| 75 | foreach ($this->filters as $filter) { |
| 76 | if ($this->is_a_calculated_column($filter->column())) { |
| 77 | $filter->apply_to_query($query); |
| 78 | } |
| 79 | } |
| 80 | })->fromSub($device_oss_query, 'device_oss')->leftJoinSub($previous_period_query, 'previous_period_stats', 'device_oss.device_os_id', '=', 'previous_period_stats.device_os_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { |
| 81 | $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { |
| 82 | $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); |
| 83 | })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('os')->when(\is_int($this->number_of_rows), function (Builder $query) { |
| 84 | $query->limit($this->number_of_rows); |
| 85 | }); |
| 86 | }); |
| 87 | Illuminate_Builder::ray($outer_query); |
| 88 | return $outer_query; |
| 89 | } |
| 90 | } |
| 91 |