PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.3.1
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.3.1
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Analytics / AnalyticsEventDto.php
wp-staging / Framework / Analytics Last commit date
Actions 3 years ago AnalyticsCleanup.php 4 years ago AnalyticsConsent.php 2 years ago AnalyticsEventDto.php 3 years ago AnalyticsSender.php 2 years ago WithAnalyticsAPI.php 4 years ago WithAnalyticsSiteInfo.php 2 years ago
AnalyticsEventDto.php
211 lines
1 <?php
2
3 namespace WPStaging\Framework\Analytics;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Filesystem\DebugLogReader;
7
8 abstract class AnalyticsEventDto implements \JsonSerializable
9 {
10 use WithAnalyticsSiteInfo;
11
12 /** @var string Which action is triggering this Analytics, eg: backup creation, staging push, etc */
13 protected $event;
14
15 /** @var string The Job ID or similar. */
16 protected $job_identifier;
17
18 /** @var string A unique hash that prevents duplicated events in a scenario where this database is restored in another site and the events are sent again. */
19 protected $event_hash;
20
21 /** @var bool Whether this job has naturally finished. Eg: Came to the expected ending. */
22 protected $is_finished = false;
23
24 /** @var bool Whether this job has started but did not finish during an expected time-frame. */
25 protected $is_stale = false;
26
27 /** @var bool Whether this job terminated in error. */
28 protected $is_error = false;
29
30 /** @var bool Whether this job has been cancelled by the user. */
31 protected $is_cancelled = false;
32
33 /** @var bool Whether the requirement check has failed for this job. */
34 protected $is_requirement_check_fail = false;
35
36 /** @var string The reason for the requirement check fail, if so. */
37 protected $requirement_fail_reason = '';
38
39 /** @var string The error message as shown in the front-end, if event terminated in error. */
40 protected $error_message;
41
42 /** @var string The last lines from the debug log file. */
43 protected $last_debug_logs;
44
45 /** @var bool An internal flag to check if this event is ready to be sent. */
46 protected $ready_to_send = false;
47
48 /** @var int A UNIX timestamp for when this event started. */
49 protected $start_time;
50
51 /** @var int A UNIX timestamp for when this event ended. */
52 protected $end_time;
53
54 /** @var int The duration in seconds between the start and end of the event. */
55 protected $duration;
56
57 /** @var array A collection of generic site information. */
58 protected $site_info;
59
60 public function __construct()
61 {
62 $this->event = $this->getEventAction();
63 $this->site_info = $this->getAnalyticsSiteInfo();
64 }
65
66 #[\ReturnTypeWillChange]
67 public function jsonSerialize()
68 {
69 return get_object_vars($this);
70 }
71
72 /**
73 * @return string The name of this analytics event.
74 */
75 abstract public function getEventAction();
76
77 public function enqueueStartEvent($jobId, $eventData)
78 {
79 $this->job_identifier = $jobId;
80 $this->start_time = time();
81 $this->event_hash = microtime(true) . rand();
82
83 try {
84 $this->saveEvent($jobId, $this);
85 } catch (\Exception $e) {
86 \WPStaging\functions\debug_log("WP STAGING: Could not register start event analytics data for job ID $jobId.", 'debug');
87 }
88 }
89
90 public function enqueueFinishEvent($jobId, $eventData, $eventOverrides = [])
91 {
92 try {
93 $event = $this->getEventByJobId($jobId);
94 } catch (\Exception $e) {
95 \WPStaging\functions\debug_log("WP STAGING: Could not register finish event analytics data for job ID $jobId", 'debug');
96
97 return;
98 }
99
100 $event->is_finished = true;
101 $event->end_time = time();
102 $event->duration = time() - $event->start_time;
103 $event->ready_to_send = true;
104
105 // Allow concrete instances of this abstract class to modify this event.
106 foreach ($eventOverrides as $key => $value) {
107 $event->$key = $value;
108 }
109
110 try {
111 $this->saveEvent($jobId, $event);
112 } catch (\Exception $e) {
113 \WPStaging\functions\debug_log("WP STAGING: Could not save finish event analytics data for job ID $jobId.", 'debug');
114 }
115 }
116
117 /**
118 * Cancel event is static as it's a generic event not related to any specific type of event.
119 */
120 public static function enqueueCancelEvent($jobId)
121 {
122 try {
123 $event = static::getEventByJobId($jobId);
124 } catch (\Exception $e) {
125 \WPStaging\functions\debug_log("WP STAGING: Could not register cancel event analytics data for job ID $jobId", 'debug');
126
127 return;
128 }
129
130 // Early bail: Already cancelled
131 if ($event->is_cancelled) {
132 return;
133 }
134
135 /*
136 * The Cancel routine may be called automatically when an error occurs
137 * to perform cleanup tasks, so let's not register the cancel event
138 * if this event is being triggered by a job that already has an error.
139 */
140 if ($event->is_error) {
141 return;
142 }
143
144 $event->is_finished = false;
145 $event->is_cancelled = true;
146 $event->end_time = time();
147 $event->duration = time() - $event->start_time;
148 $event->ready_to_send = true;
149
150 try {
151 static::saveEvent($jobId, $event);
152 } catch (\Exception $e) {
153 \WPStaging\functions\debug_log("WP STAGING: Could not save cancel event analytics data for job ID $jobId.", 'debug');
154 }
155 }
156
157 /**
158 * Error event is static as it's a generic event not related to any specific type of event.
159 */
160 public static function enqueueErrorEvent($jobId, $errorMessage)
161 {
162 try {
163 $event = static::getEventByJobId($jobId);
164 } catch (\Exception $e) {
165 \WPStaging\functions\debug_log("WP STAGING: Could not register cancel event analytics data for job ID $jobId", 'debug');
166
167 return;
168 }
169
170 $lastDebugLogErrors = WPStaging::make(DebugLogReader::class)->getLastLogEntries(8 * KB_IN_BYTES);
171
172 $event->is_finished = false;
173 $event->is_error = true;
174 $event->error_message = $errorMessage;
175 $event->last_debug_logs = $lastDebugLogErrors;
176 $event->end_time = time();
177 $event->duration = time() - $event->start_time;
178 $event->ready_to_send = true;
179
180 try {
181 static::saveEvent($jobId, $event);
182 } catch (\Exception $e) {
183 \WPStaging\functions\debug_log("WP STAGING: Could not save cancel event analytics data for job ID $jobId.", 'debug');
184 }
185 }
186
187 protected static function getEventByJobId($jobId)
188 {
189 if (!$event = get_option("wpstg_analytics_event_$jobId")) {
190 throw new \UnexpectedValueException();
191 }
192
193 $event = json_decode($event);
194
195 if (empty($event) || !is_object($event)) {
196 throw new \UnexpectedValueException();
197 }
198
199 return $event;
200 }
201
202 protected static function saveEvent($jobId, $event)
203 {
204 $event = wp_json_encode($event);
205
206 if (!update_option("wpstg_analytics_event_$jobId", $event, false)) {
207 throw new \UnexpectedValueException();
208 }
209 }
210 }
211