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