PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.0
Independent Analytics – WordPress Analytics Plugin v2.15.0
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 / Rows.php
independent-analytics / IAWP / Rows Last commit date
Campaign_Landing_Pages.php 4 days ago Campaign_UTM_Campaigns.php 4 days ago Campaign_UTM_Mediums.php 4 days ago Campaign_UTM_Sources.php 4 days ago Campaigns.php 4 days ago Cities.php 4 days ago Countries.php 4 days ago Device_Browsers.php 4 days ago Device_OSS.php 4 days ago Device_Types.php 4 days ago Filter.php 5 months ago Forms.php 5 months ago Journeys.php 3 months ago Link_Patterns.php 4 months ago Links.php 5 months ago Pages.php 4 days ago Referrer_Types.php 4 days ago Referrers.php 4 days ago Rows.php 4 days ago
Rows.php
191 lines
1 <?php
2
3 namespace IAWP\Rows;
4
5 use IAWP\Date_Range\Date_Range;
6 use IAWP\Examiner_Config;
7 use IAWP\Illuminate_Builder;
8 use IAWP\Query;
9 use IAWP\Sort_Configuration;
10 use IAWP\Tables;
11 use IAWPSCOPED\Illuminate\Database\Query\Builder;
12 /** @internal */
13 abstract class Rows
14 {
15 protected $tables = Tables::class;
16 protected $date_range;
17 protected $number_of_rows;
18 /** @var Filter[] */
19 protected $filters;
20 protected $sort_configuration;
21 protected $filter_logic;
22 protected $solo_record_id = null;
23 protected $examiner_config = null;
24 private $rows = null;
25 public function __construct(Date_Range $date_range, Sort_Configuration $sort_configuration, ?int $number_of_rows = null, ?array $filters = null, ?string $filter_logic = null)
26 {
27 $this->date_range = $date_range;
28 $this->sort_configuration = $sort_configuration;
29 $this->number_of_rows = $number_of_rows;
30 $this->filters = $filters ?? [];
31 $this->filter_logic = \in_array($filter_logic, ['and', 'or']) ? $filter_logic : 'and';
32 }
33 protected abstract function fetch_rows() : array;
34 public abstract function attach_filters(Builder $query) : void;
35 protected abstract function sort_tie_breaker_column() : string;
36 /**
37 * Used to limit the rows to just a single record. This is useful if you want a single page,
38 * referrer, etc. row, and you know the records database id.
39 *
40 * @param int $id
41 *
42 * @return void
43 */
44 public function limit_to(int $id) : void
45 {
46 $this->solo_record_id = $id;
47 }
48 public function for_examiner(Examiner_Config $config)
49 {
50 $this->examiner_config = $config;
51 }
52 public function rows()
53 {
54 if (\is_array($this->rows)) {
55 return $this->rows;
56 }
57 $this->rows = $this->fetch_rows();
58 return $this->rows;
59 }
60 protected function only_filtering_by_record_columns() : bool
61 {
62 if (\count($this->filters) === 0) {
63 return \true;
64 }
65 foreach ($this->filters as $filter) {
66 if ($filter->is_calculated_column()) {
67 return \false;
68 }
69 }
70 return \true;
71 }
72 protected function only_filtering_by_aggregate_columns() : bool
73 {
74 if (\count($this->filters) === 0) {
75 return \false;
76 }
77 foreach ($this->filters as $filter) {
78 if ($filter->is_concrete_column()) {
79 return \false;
80 }
81 }
82 return \true;
83 }
84 protected function filtering_by_mixed_columns() : bool
85 {
86 if (\count($this->filters) === 0) {
87 return \false;
88 }
89 $has_record_column = \false;
90 $has_aggregate_column = \false;
91 foreach ($this->filters as $filter) {
92 if ($filter->is_calculated_column()) {
93 $has_aggregate_column = \true;
94 } else {
95 $has_record_column = \true;
96 }
97 if ($has_record_column && $has_aggregate_column) {
98 return \true;
99 }
100 }
101 return \false;
102 }
103 protected function get_current_period_iso_range() : array
104 {
105 return [$this->date_range->iso_start(), $this->date_range->iso_end()];
106 }
107 protected function is_real_time() : bool
108 {
109 $difference_in_seconds = $this->date_range->end()->getTimestamp() - $this->date_range->start()->getTimestamp();
110 $one_hour_in_seconds = 3600;
111 return $difference_in_seconds < $one_hour_in_seconds;
112 }
113 protected function get_previous_period_iso_range() : array
114 {
115 return [$this->date_range->previous_period()->iso_start(), $this->date_range->previous_period()->iso_end()];
116 }
117 protected function get_form_submissions_query() : Builder
118 {
119 $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS);
120 return Illuminate_Builder::new()->select(['form_id', 'view_id'])->selectRaw('COUNT(*) AS form_submissions')->from($form_submissions_table, 'form_submissions')->whereBetween('created_at', $this->get_current_period_iso_range())->groupBy(['form_id', 'view_id']);
121 }
122 protected function apply_record_filters(Builder $query) : void
123 {
124 $should_apply_record_filters = $this->using_logical_and_operator() || $this->only_filtering_by_record_columns();
125 if (!$should_apply_record_filters) {
126 return;
127 }
128 if ($this->using_logical_or_operator()) {
129 $query->where(function (Builder $query) {
130 foreach ($this->filters as $index => $filter) {
131 $filter->apply_to_query($query, \IAWP\Rows\Filter::$RECORD_FILTER, $index > 0);
132 }
133 });
134 return;
135 }
136 foreach ($this->filters as $filter) {
137 if ($filter->is_concrete_column()) {
138 $filter->apply_to_query($query, \IAWP\Rows\Filter::$RECORD_FILTER);
139 }
140 }
141 }
142 protected function can_order_and_limit_at_record_level() : bool
143 {
144 return $this->sort_configuration->the_column()->is_concrete_column() && $this->only_filtering_by_record_columns();
145 }
146 protected function apply_aggregate_filters(Builder $query) : void
147 {
148 $should_apply_aggregate_filters = $this->using_logical_and_operator() || $this->using_logical_or_operator() && $this->only_filtering_by_aggregate_columns();
149 if (!$should_apply_aggregate_filters) {
150 return;
151 }
152 if ($this->using_logical_or_operator()) {
153 $query->where(function (Builder $query) {
154 foreach ($this->filters as $index => $filter) {
155 $filter->apply_to_query($query, \IAWP\Rows\Filter::$AGGREGATE_FILTER, $index > 0);
156 }
157 });
158 return;
159 }
160 foreach ($this->filters as $filter) {
161 if ($filter->is_calculated_column()) {
162 $filter->apply_to_query($query, \IAWP\Rows\Filter::$AGGREGATE_FILTER);
163 }
164 }
165 }
166 protected function apply_or_filters(Builder $query) : void
167 {
168 $query->where(function (Builder $query) {
169 foreach ($this->filters as $index => $filter) {
170 $filter->apply_to_query($query, \IAWP\Rows\Filter::$OUTER_FILTER, $index > 0);
171 }
172 });
173 }
174 protected function using_logical_or_operator() : bool
175 {
176 return $this->filter_logic === 'or' && \count($this->filters) > 1;
177 }
178 protected function using_logical_and_operator() : bool
179 {
180 return !$this->using_logical_or_operator();
181 }
182 protected function apply_order_and_limit(Builder $query, string $sort_column) : void
183 {
184 $query->when($this->sort_configuration->the_column()->is_nullable(), function (Builder $query) use($sort_column) {
185 $query->orderByRaw("CASE WHEN {$sort_column} IS NULL THEN 1 ELSE 0 END");
186 })->orderBy($sort_column, $this->sort_configuration->direction())->orderBy($this->sort_tie_breaker_column())->when(\is_int($this->number_of_rows), function (Builder $query) {
187 $query->limit($this->number_of_rows);
188 });
189 }
190 }
191