PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 2.1.39
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v2.1.39
3.1.13 3.1.12 3.1.11 3.1.10 3.1.9 3.1.8 3.1.7 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 All 122 releases
firebox / Inc / Core / Migrator.php

Migrator.php in FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment 2.1.39, at Inc/Core/Migrator.php

521 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package FireBox
4 * @version 2.1.39 Free
5 *
6 * @author FirePlugins <info@fireplugins.com>
7 * @link https://www.fireplugins.com
8 * @copyright Copyright © 2025 FirePlugins All Rights Reserved
9 * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
10 */
11
12 namespace FireBox\Core;
13
14 if (!defined('ABSPATH'))
15 {
16 exit; // Exit if accessed directly.
17 }
18
19 use FireBox\Core\Helpers\Form\Form;
20
21 class Migrator
22 {
23 /**
24 * The currently installed version.
25 *
26 * @var string
27 */
28 private $installedVersion;
29
30 /**
31 * Whether we run a migration.
32 *
33 * @var bool
34 */
35 private $run = false;
36
37 public function __construct($installedVersion = '')
38 {
39 $this->installedVersion = $installedVersion;
40 }
41
42 public function run()
43 {
44 if (!$this->installedVersion)
45 {
46 return;
47 }
48
49 $this->moveFireBoxDataToUploadsDirectory();
50 $this->installFormsTables();
51 $this->improveIndexes();
52 $this->updatePublishingRulesToConditionBuilder();
53 $this->updateEcommerceProductsInCartConditions();
54 $this->updateAnalyticsStoragePeriodSetting();
55 $this->update213version();
56 $this->addMissingCapabilities();
57
58
59 // Update firebox version
60 if ($this->run)
61 {
62 // Update version
63 update_option('firebox_version', FBOX_VERSION);
64 }
65 }
66
67 /**
68 * Moves plugin data to its own /wp-content/uploads/firebox folder.
69 *
70 * @since 1.1.10
71 *
72 * @return void
73 */
74 private function moveFireBoxDataToUploadsDirectory()
75 {
76 if (version_compare($this->installedVersion, '1.1.10', '>='))
77 {
78 return;
79 }
80
81 // Create dirs
82 \FireBox\Core\Helpers\Activation::createLibraryDirectories();
83
84 $this->run = true;
85 }
86
87 /**
88 * Creates the forms tables.
89 *
90 * @since 1.2.0
91 *
92 * @return void
93 */
94 private function installFormsTables()
95 {
96 if (version_compare($this->installedVersion, '1.2.0', '>='))
97 {
98 return;
99 }
100
101 if (!class_exists('Activation'))
102 {
103 require_once FBOX_PLUGIN_DIR . '/Inc/Framework/Inc/Admin/Includes/Activation.php';
104 }
105 $activation = new \Activation(firebox()->hook_data);
106 $activation->initTables();
107
108 $this->run = true;
109 }
110
111 /**
112 * Improves indexes on form and box logs tables.
113 *
114 * @since 1.2.4
115 *
116 * @return void
117 */
118 private function improveIndexes()
119 {
120 if (version_compare($this->installedVersion, '1.2.4', '>='))
121 {
122 return;
123 }
124
125 if (!$this->hasIndex('idx_box_id', 'firebox_logs'))
126 {
127 global $wpdb;
128 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs ADD INDEX `idx_box_id` (`box`, `id`)");
129 }
130
131 if (!$this->hasIndex('idx_meta_key', 'firebox_submission_meta'))
132 {
133 global $wpdb;
134 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_submission_meta ADD INDEX `idx_meta_key` (`meta_key`)");
135 }
136
137 $this->run = true;
138 }
139
140 /**
141 * Update old Publishing Rules to Condition Builder.
142 *
143 * @since 2.0.0
144 *
145 * @return void
146 */
147 private function updatePublishingRulesToConditionBuilder()
148 {
149 if (version_compare($this->installedVersion, '2.0.0', '>='))
150 {
151 return;
152 }
153
154 // Get all boxes, regardless of post status, thus we pass [] to ensure all popups are returned.
155 $boxes = \FireBox\Core\Helpers\BoxHelper::getAllBoxes([]);
156
157 if (!$boxes->posts)
158 {
159 $this->run = true;
160 return;
161 }
162
163 foreach ($boxes->posts as $box)
164 {
165 // Get post meta and add it to its object
166 $meta = \FireBox\Core\Helpers\BoxHelper::getMeta($box->ID);
167
168 // Skip popup that already has rules
169 if (isset($meta['rules']))
170 {
171 continue;
172 }
173
174 $box->params = new \FPFramework\Libs\Registry($meta);
175
176 // Pass only params
177 \FPFramework\Base\Conditions\Migrator::run($box->params);
178
179 // Update popup settings
180 update_post_meta($box->ID, 'fpframework_meta_settings', wp_slash(json_decode(wp_json_encode($box->params), true)));
181 }
182
183 $this->run = true;
184 }
185
186 /**
187 * Updates the following conditions to match the new condition settings.
188 *
189 * EDD\CartContainsProducts
190 * WooCommerce\CartContainsProducts
191 *
192 * @since 2.0.10
193 *
194 * @return void
195 */
196 private function updateEcommerceProductsInCartConditions()
197 {
198 if (version_compare($this->installedVersion, '2.0.10', '>='))
199 {
200 return;
201 }
202
203 // Get all boxes, regardless of post status, thus we pass [] to ensure all popups are returned.
204 $boxes = \FireBox\Core\Helpers\BoxHelper::getAllBoxes([]);
205
206 if (!$boxes->posts)
207 {
208 $this->run = true;
209 return;
210 }
211
212 foreach ($boxes->posts as $box)
213 {
214 $meta = \FireBox\Core\Helpers\BoxHelper::getMeta($box->ID);
215
216 if (!isset($meta['rules']) || !is_array($meta['rules']))
217 {
218 continue;
219 }
220
221 $allowed_rules = [
222 'EDD\CartContainsProducts',
223 'WooCommerce\CartContainsProducts'
224 ];
225
226 $changed = false;
227
228 foreach ($meta['rules'] as &$ruleset)
229 {
230 if (!isset($ruleset['rules']))
231 {
232 continue;
233 }
234
235 foreach ($ruleset['rules'] as &$rule)
236 {
237 if (!isset($rule['name']))
238 {
239 continue;
240 }
241
242 if (!in_array($rule['name'], $allowed_rules))
243 {
244 continue;
245 }
246
247 if (!isset($rule['value']))
248 {
249 continue;
250 }
251
252 if (!is_array($rule['value']))
253 {
254 continue;
255 }
256
257 if (!count($rule['value']))
258 {
259 continue;
260 }
261
262 $changed = true;
263
264 $rule['value'] = array_map(function($id) {
265 // Old value wasn't an array, skip if new value was found
266 if (is_array($id))
267 {
268 return $id;
269 }
270
271 return [
272 'value' => $id,
273 'quantity_operator' => 'any',
274 'quantity_value1' => '1',
275 'quantity_value2' => '1'
276 ];
277 }, $rule['value']);
278 }
279 }
280
281 if (!$changed)
282 {
283 continue;
284 }
285
286 update_post_meta($box->ID, 'fpframework_meta_settings', wp_slash(json_decode(wp_json_encode($meta), true)));
287 }
288
289 $this->run = true;
290 }
291
292 /**
293 * Updates the Analytics Storage Period setting.
294 *
295 * @since 2.1.1
296 *
297 * @return void
298 */
299 public function updateAnalyticsStoragePeriodSetting()
300 {
301 if (version_compare($this->installedVersion, '2.1.1', '>='))
302 {
303 return;
304 }
305
306 $params = get_option('firebox_settings');
307
308 $statsdays = isset($params['statsdays']) ? $params['statsdays'] : 730;
309 $statsdays_custom = isset($params['statsdays_custom']) ? $params['statsdays_custom'] : false;
310
311 if ($statsdays === 'custom')
312 {
313 $statsdays = $statsdays_custom;
314 }
315
316 $statsdays = (int) $statsdays;
317
318 if ($statsdays <= 365)
319 {
320 $statsdays = 365;
321 }
322 else if ($statsdays <= 365 * 2)
323 {
324 $statsdays = 365 * 2;
325 }
326 else
327 {
328 $statsdays = 365 * 5;
329 }
330
331 $params['statsdays'] = $statsdays;
332
333 update_option('firebox_settings', $params);
334
335 $this->run = true;
336 }
337
338 public function update213version()
339 {
340 $this->updateLogsDetailsParamsColumn();
341 $this->moveFormConversionsToLogsDetailsTable();
342 }
343
344 /**
345 * Adds a new column called event_source after event column.
346 * Renames the params column in the logs details table to event_label.
347 *
348 * @since 2.1.4
349 *
350 * @return void
351 */
352 public function updateLogsDetailsParamsColumn()
353 {
354 if (version_compare($this->installedVersion, '2.1.4', '>='))
355 {
356 return;
357 }
358
359 global $wpdb;
360
361 // If has column params
362 $row = $wpdb->get_results("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = '{$wpdb->dbname}' AND table_name = '{$wpdb->prefix}firebox_logs_details' AND column_name = 'params'");
363 if (!$row)
364 {
365 $this->run = true;
366 return;
367 }
368
369 // Add column "event_source" after "event"
370 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD COLUMN `event_source` varchar(200) NOT NULL AFTER `event`");
371
372 // Rename params to event_label
373 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details CHANGE COLUMN `params` `event_label` text NOT NULL");
374
375 $this->run = true;
376 }
377
378 /**
379 * Moves form conversions from submission meta table to logs details table.
380 *
381 * @since 2.1.4
382 *
383 * @return void
384 */
385 private function moveFormConversionsToLogsDetailsTable()
386 {
387 if (version_compare($this->installedVersion, '2.1.4', '>='))
388 {
389 return;
390 }
391
392 global $wpdb;
393
394 // Get all submission meta data
395 $boxlogids = firebox()->tables->submissionmeta->getResults([
396 'select' => [
397 "{$wpdb->prefix}firebox_submission_meta.id",
398 'l.box',
399 's.form_id',
400 "{$wpdb->prefix}firebox_submission_meta.meta_value",
401 "{$wpdb->prefix}firebox_submission_meta.created_at"
402 ],
403 'where' => [
404 'meta_key' => " = '" . esc_sql('box_log_id') . "'"
405 ],
406 'join' => [
407 "LEFT JOIN" => " {$wpdb->prefix}firebox_submissions as s ON s.id = submission_id LEFT JOIN {$wpdb->prefix}firebox_logs as l ON l.id = meta_value",
408 ]
409 ]);
410
411 if (!$boxlogids)
412 {
413 $this->run = true;
414 return;
415 }
416
417 global $wpdb;
418
419 // Migrate to the box logs details table
420 foreach ($boxlogids as $row)
421 {
422 if (!$row->box)
423 {
424 continue;
425 }
426
427 $form = Form::getFormByID($row->form_id);
428
429 $data = [
430 'log_id' => $row->meta_value,
431 'event' => 'conversion',
432 'event_source' => 'form',
433 'event_label' => isset($form['block']['attrs']['formName']) ? $form['block']['attrs']['formName'] : 'FireBox #' . $row->box . ' Form',
434 'date' => $row->created_at
435 ];
436
437 firebox()->tables->boxlogdetails->insert($data);
438 }
439
440 // Delete all submission_meta rows
441 $ids = implode(',', array_map('intval', array_column($boxlogids, 'id')));
442 $sm_table_name = firebox()->tables->submissionmeta->getFullTableName();
443 $wpdb->query("DELETE FROM $sm_table_name WHERE id IN($ids)");// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
444
445 $this->run = true;
446 }
447
448 public function addMissingCapabilities()
449 {
450 if (version_compare($this->installedVersion, '2.1.15', '>='))
451 {
452 return;
453 }
454
455 $cap_name = 'read_fireboxes';
456
457 $admin = get_role('administrator');
458
459 if ($admin)
460 {
461 if ($admin->has_cap($cap_name))
462 {
463 return true;
464 }
465
466 $admin->add_cap($cap_name);
467 }
468 else
469 {
470 $roles = get_editable_roles();
471
472 foreach ($roles as $role_name => $data)
473 {
474 if (isset($data['capabilities']['manage_options']) && $data['capabilities']['manage_options'])
475 {
476 $role = get_role($role_name);
477
478 if ($role->has_cap($cap_name))
479 {
480 continue;
481 }
482
483 $role->add_cap($cap_name);
484 }
485 }
486 }
487
488 wp_get_current_user()->get_role_caps();
489
490 return true;
491 }
492
493
494
495 /**
496 * Checks whether an index exists in a table.
497 *
498 * @param string $index
499 * @param string $table
500 *
501 * @return bool
502 */
503 private function hasIndex($index = '', $table = '')
504 {
505 if (empty($index) || empty($table))
506 {
507 return;
508 }
509
510 global $wpdb;
511
512 $existing = $wpdb->get_row("SHOW CREATE TABLE `{$wpdb->prefix}{$table}`", ARRAY_N);// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
513
514 if (isset($existing[1]) && strpos(strtolower($existing[1]), 'key `' . $index . '` (') !== false)
515 {
516 return true;
517 }
518
519 return false;
520 }
521 }