PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.8.4
Independent Analytics – WordPress Analytics Plugin v2.8.4
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 / Cities.php
independent-analytics / IAWP / Rows Last commit date
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
Cities.php
93 lines
1 <?php
2
3 namespace IAWP\Rows;
4
5 use IAWP\Form_Submissions\Form;
6 use IAWP\Illuminate_Builder;
7 use IAWP\Models\Geo;
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 Cities extends \IAWP\Rows\Rows
14 {
15 public function attach_filters(Builder $query) : void
16 {
17 $query->joinSub($this->query(\true), 'city_rows', function (JoinClause $join) {
18 $join->on('city_rows.city_id', '=', 'sessions.city_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 Geo($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 $countries_table = Query::get_table_name(Query::COUNTRIES);
37 $cities_table = Query::get_table_name(Query::CITIES);
38 $orders_query = Illuminate_Builder::get_builder();
39 $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');
40 $cities_query = Illuminate_Builder::get_builder();
41 $cities_query->select('countries.country_id', 'countries.country_code', 'countries.country', 'countries.continent', 'cities.subdivision', 'cities.city', 'cities.city_id')->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) {
42 foreach (Form::get_forms() as $form) {
43 $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]);
44 }
45 })->from($views_table, 'views')->leftJoin($cities_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) {
46 $join->on('views.session_id', '=', 'sessions.session_id');
47 })->join($cities_query->raw($cities_table . ' AS cities'), function (JoinClause $join) {
48 $join->on('sessions.city_id', '=', 'cities.city_id');
49 })->join($cities_query->raw($countries_table . ' AS countries'), function (JoinClause $join) {
50 $join->on('cities.country_id', '=', 'countries.country_id');
51 })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) {
52 $join->on('the_orders.view_id', '=', 'views.id');
53 })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) {
54 $join->on('form_submissions.view_id', '=', 'views.id');
55 })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) {
56 $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range());
57 })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) {
58 foreach ($this->filters as $filter) {
59 if (!$this->is_a_calculated_column($filter->column())) {
60 $filter->apply_to_query($query);
61 }
62 }
63 })->groupBy('cities.city_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) {
64 $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) {
65 $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END");
66 })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('city')->when(\is_int($this->number_of_rows), function (Builder $query) {
67 $query->limit($this->number_of_rows);
68 });
69 });
70 $previous_period_query = Illuminate_Builder::get_builder();
71 $previous_period_query->select(['sessions.city_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.city_id');
72 $outer_query = Illuminate_Builder::get_builder();
73 $outer_query->selectRaw('cities.*')->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) {
74 foreach (Form::get_forms() as $form) {
75 $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}");
76 }
77 })->when(\count($this->filters) > 0, function (Builder $query) {
78 foreach ($this->filters as $filter) {
79 if ($this->is_a_calculated_column($filter->column())) {
80 $filter->apply_to_query($query);
81 }
82 }
83 })->fromSub($cities_query, 'cities')->leftJoinSub($previous_period_query, 'previous_period_stats', 'cities.city_id', '=', 'previous_period_stats.city_id')->when($this->is_using_a_calculated_column(), function (Builder $query) {
84 $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) {
85 $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END");
86 })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('city')->when(\is_int($this->number_of_rows), function (Builder $query) {
87 $query->limit($this->number_of_rows);
88 });
89 });
90 return $outer_query;
91 }
92 }
93