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 / Pages.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
Pages.php
129 lines
1 <?php
2
3 namespace IAWP\Rows;
4
5 use IAWP\Database;
6 use IAWP\Form_Submissions\Form;
7 use IAWP\Illuminate_Builder;
8 use IAWP\Models\Page;
9 use IAWP\Query;
10 use IAWP\Query_Taps;
11 use IAWPSCOPED\Illuminate\Database\Query\Builder;
12 use IAWPSCOPED\Illuminate\Database\Query\JoinClause;
13 /** @internal */
14 class Pages extends \IAWP\Rows\Rows
15 {
16 private static $has_wp_comments_table = null;
17 public function attach_filters(Builder $query) : void
18 {
19 $query->joinSub($this->query(\true), 'page_rows', function (JoinClause $join) {
20 $join->on('page_rows.id', '=', 'views.resource_id');
21 });
22 }
23 protected function fetch_rows() : array
24 {
25 $rows = $this->query()->get()->all();
26 return \array_map(function (object $row) {
27 return Page::from_row($row);
28 }, $rows);
29 }
30 private function has_wp_comments_table() : bool
31 {
32 if (\is_bool(self::$has_wp_comments_table)) {
33 return self::$has_wp_comments_table;
34 }
35 global $wpdb;
36 self::$has_wp_comments_table = Database::has_table($wpdb->prefix . 'comments');
37 return self::$has_wp_comments_table;
38 }
39 private function query(?bool $skip_pagination = \false) : Builder
40 {
41 if ($skip_pagination) {
42 $this->number_of_rows = null;
43 }
44 $views_table = Query::get_table_name(Query::VIEWS);
45 $sessions_table = Query::get_table_name(Query::SESSIONS);
46 $resources_table = Query::get_table_name(Query::RESOURCES);
47 $orders_table = Query::get_table_name(Query::ORDERS);
48 $database_sort_columns = ['title' => 'cached_title', 'url' => 'cached_url', 'author' => 'cached_author', 'type' => 'cached_type_label', 'date' => 'cached_date', 'category' => 'cached_category'];
49 $sort_column = $this->sort_configuration->column();
50 foreach ($database_sort_columns as $key => $value) {
51 if ($sort_column === $key) {
52 $sort_column = $value;
53 }
54 }
55 $orders_query = Illuminate_Builder::get_builder();
56 $orders_query->select(['sessions.initial_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')->leftJoin($orders_query->raw($views_table . ' AS views'), function (JoinClause $join) {
57 $join->on('orders.view_id', '=', 'views.id');
58 })->leftJoin($orders_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) {
59 $join->on('views.session_id', '=', 'sessions.session_id');
60 })->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id');
61 $pages_query = Illuminate_Builder::get_builder();
62 $pages_query->select('resources.*')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT IF(initial_view.resource_id = resources.id, sessions.visitor_id, NULL)) AS landing_page_visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('AVG(TIMESTAMPDIFF(SECOND, views.viewed_at, views.next_viewed_at)) AS average_view_duration')->selectRaw('COUNT(DISTINCT IF(resources.id = initial_view.resource_id, sessions.session_id, NULL)) AS entrances')->selectRaw('COUNT(DISTINCT IF((resources.id = final_view.resource_id OR (resources.id = initial_view.resource_id AND sessions.final_view_id IS NULL)), sessions.session_id, NULL)) AS exits')->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(wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) {
63 foreach (Form::get_forms() as $form) {
64 $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]);
65 }
66 })->from($views_table, 'views')->leftJoin($pages_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) {
67 $join->on('views.session_id', '=', 'sessions.session_id');
68 })->leftJoin($pages_query->raw($resources_table . ' AS resources'), function (JoinClause $join) {
69 $join->on('views.resource_id', '=', 'resources.id');
70 })->leftJoin($pages_query->raw($views_table . ' AS initial_view'), function (JoinClause $join) {
71 $join->on('sessions.initial_view_id', '=', 'initial_view.id');
72 })->leftJoin($pages_query->raw($views_table . ' AS final_view'), function (JoinClause $join) {
73 $join->on('sessions.final_view_id', '=', 'final_view.id');
74 })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) {
75 $join->on('the_orders.view_id', '=', 'views.id');
76 })->tap(Query_Taps::tap_authored_content_check(\false))->when($this->has_wp_comments_table(), function (Builder $query) {
77 $query->selectRaw('IFNULL(comments.comments, 0) AS comments');
78 $query->leftJoinSub($this->get_comments_query(), 'comments', 'comments.resource_id', '=', 'resources.id');
79 }, function (Builder $query) {
80 $query->selectRaw('0 AS comments');
81 })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) {
82 $join->on('form_submissions.view_id', '=', 'views.id');
83 })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) {
84 $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range());
85 })->when(\count($this->filters) > 0, function (Builder $query) {
86 foreach ($this->filters as $filter) {
87 if (!$this->is_a_calculated_column($filter->column())) {
88 $filter->apply_to_query($query);
89 }
90 }
91 })->groupBy('resources.id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) use($sort_column) {
92 $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) use($sort_column) {
93 $query->orderByRaw("CASE WHEN {$sort_column} IS NULL THEN 1 ELSE 0 END");
94 })->orderBy($sort_column, $this->sort_configuration->direction())->orderBy('cached_title')->when(\is_int($this->number_of_rows), function (Builder $query) {
95 $query->limit($this->number_of_rows);
96 });
97 });
98 $previous_period_query = Illuminate_Builder::get_builder();
99 $previous_period_query->select(['views.resource_id'])->selectRaw('COUNT(*) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($views_table, 'views')->join($previous_period_query->raw($sessions_table . ' AS sessions'), 'views.session_id', '=', 'sessions.session_id')->whereBetween('views.viewed_at', $this->get_previous_period_iso_range())->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('views.resource_id');
100 $outer_query = Illuminate_Builder::get_builder();
101 $outer_query->selectRaw('pages.*')->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('IFNULL((exits / views) * 100, 0) AS exit_percent')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS UNSIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / landing_page_visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / landing_page_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) {
102 foreach (Form::get_forms() as $form) {
103 $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}");
104 }
105 })->when(\count($this->filters) > 0, function (Builder $query) {
106 foreach ($this->filters as $filter) {
107 if ($this->is_a_calculated_column($filter->column())) {
108 $filter->apply_to_query($query);
109 }
110 }
111 })->fromSub($pages_query, 'pages')->leftJoinSub($previous_period_query, 'previous_period_stats', 'pages.id', '=', 'previous_period_stats.resource_id')->when($this->is_using_a_calculated_column(), function (Builder $query) use($sort_column) {
112 $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) use($sort_column) {
113 $query->orderByRaw("CASE WHEN {$sort_column} IS NULL THEN 1 ELSE 0 END");
114 })->orderBy($sort_column, $this->sort_configuration->direction())->orderBy('cached_title')->when(\is_int($this->number_of_rows), function (Builder $query) {
115 $query->limit($this->number_of_rows);
116 });
117 });
118 return $outer_query;
119 }
120 private function get_comments_query() : Builder
121 {
122 global $wpdb;
123 $comments_table = $wpdb->prefix . 'comments';
124 $resources_table = Query::get_table_name(Query::RESOURCES);
125 $comments_query = Illuminate_Builder::get_builder()->select(['resources.id AS resource_id'])->selectRaw('COUNT(*) AS comments')->from($comments_table, 'comments')->join($resources_table . " AS resources", 'comments.comment_post_ID', '=', 'resources.singular_id')->where('comments.comment_type', '=', 'comment')->where('comments.comment_approved', '=', '1')->whereBetween('comments.comment_date_gmt', $this->get_current_period_iso_range())->groupBy('resources.id');
126 return $comments_query;
127 }
128 }
129