PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 3.1.9
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v3.1.9
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 3.1.9, at Inc/Core/Migrator.php

605 lines 13.1 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 3.1.9 Free
5 *
6 * @author FirePlugins <info@fireplugins.com>
7 * @link https://www.fireplugins.com
8 * @copyright Copyright © 2026 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 $this->addNewIndexes();
60 $this->addSubmissionsIndexes();
61
62 // Update firebox version
63 if ($this->run)
64 {
65 // Update version
66 update_option('firebox_version', FBOX_VERSION);
67 }
68 }
69
70 /**
71 * Moves plugin data to its own /wp-content/uploads/firebox folder.
72 *
73 * @since 1.1.10
74 *
75 * @return void
76 */
77 private function moveFireBoxDataToUploadsDirectory()
78 {
79 if (version_compare($this->installedVersion, '1.1.10', '>='))
80 {
81 return;
82 }
83
84 // Create dirs
85 \FireBox\Core\Helpers\Activation::createLibraryDirectories();
86
87 $this->run = true;
88 }
89
90 /**
91 * Creates the forms tables.
92 *
93 * @since 1.2.0
94 *
95 * @return void
96 */
97 private function installFormsTables()
98 {
99 if (version_compare($this->installedVersion, '1.2.0', '>='))
100 {
101 return;
102 }
103
104 if (!class_exists('Activation'))
105 {
106 require_once FBOX_PLUGIN_DIR . '/Inc/Framework/Inc/Admin/Includes/Activation.php';
107 }
108 $activation = new \Activation(firebox()->hook_data);
109 $activation->initTables();
110
111 $this->run = true;
112 }
113
114 /**
115 * Improves indexes on form and box logs tables.
116 *
117 * @since 1.2.4
118 *
119 * @return void
120 */
121 private function improveIndexes()
122 {
123 if (version_compare($this->installedVersion, '1.2.4', '>='))
124 {
125 return;
126 }
127
128 if (!$this->hasIndex('idx_box_id', 'firebox_logs'))
129 {
130 global $wpdb;
131 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs ADD INDEX `idx_box_id` (`box`, `id`)");
132 }
133
134 if (!$this->hasIndex('idx_meta_key', 'firebox_submission_meta'))
135 {
136 global $wpdb;
137 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_submission_meta ADD INDEX `idx_meta_key` (`meta_key`)");
138 }
139
140 $this->run = true;
141 }
142
143 /**
144 * Update old Publishing Rules to Condition Builder.
145 *
146 * @since 2.0.0
147 *
148 * @return void
149 */
150 private function updatePublishingRulesToConditionBuilder()
151 {
152 if (version_compare($this->installedVersion, '2.0.0', '>='))
153 {
154 return;
155 }
156
157 // Get all boxes, regardless of post status, thus we pass [] to ensure all popups are returned.
158 $boxes = \FireBox\Core\Helpers\BoxHelper::getAllBoxes([]);
159
160 if (!$boxes->posts)
161 {
162 $this->run = true;
163 return;
164 }
165
166 foreach ($boxes->posts as $box)
167 {
168 // Get post meta and add it to its object
169 $meta = \FireBox\Core\Helpers\BoxHelper::getMeta($box->ID);
170
171 // Skip popup that already has rules
172 if (isset($meta['rules']))
173 {
174 continue;
175 }
176
177 $box->params = new \FPFramework\Libs\Registry($meta);
178
179 // Pass only params
180 \FPFramework\Base\Conditions\Migrator::run($box->params);
181
182 // Update popup settings
183 update_post_meta($box->ID, 'fpframework_meta_settings', wp_slash(json_decode(wp_json_encode($box->params), true)));
184 }
185
186 $this->run = true;
187 }
188
189 /**
190 * Updates the following conditions to match the new condition settings.
191 *
192 * EDD\CartContainsProducts
193 * WooCommerce\CartContainsProducts
194 *
195 * @since 2.0.10
196 *
197 * @return void
198 */
199 private function updateEcommerceProductsInCartConditions()
200 {
201 if (version_compare($this->installedVersion, '2.0.10', '>='))
202 {
203 return;
204 }
205
206 // Get all boxes, regardless of post status, thus we pass [] to ensure all popups are returned.
207 $boxes = \FireBox\Core\Helpers\BoxHelper::getAllBoxes([]);
208
209 if (!$boxes->posts)
210 {
211 $this->run = true;
212 return;
213 }
214
215 foreach ($boxes->posts as $box)
216 {
217 $meta = \FireBox\Core\Helpers\BoxHelper::getMeta($box->ID);
218
219 if (!isset($meta['rules']) || !is_array($meta['rules']))
220 {
221 continue;
222 }
223
224 $allowed_rules = [
225 'EDD\CartContainsProducts',
226 'WooCommerce\CartContainsProducts'
227 ];
228
229 $changed = false;
230
231 foreach ($meta['rules'] as &$ruleset)
232 {
233 if (!isset($ruleset['rules']))
234 {
235 continue;
236 }
237
238 foreach ($ruleset['rules'] as &$rule)
239 {
240 if (!isset($rule['name']))
241 {
242 continue;
243 }
244
245 if (!in_array($rule['name'], $allowed_rules))
246 {
247 continue;
248 }
249
250 if (!isset($rule['value']))
251 {
252 continue;
253 }
254
255 if (!is_array($rule['value']))
256 {
257 continue;
258 }
259
260 if (!count($rule['value']))
261 {
262 continue;
263 }
264
265 $changed = true;
266
267 $rule['value'] = array_map(function($id) {
268 // Old value wasn't an array, skip if new value was found
269 if (is_array($id))
270 {
271 return $id;
272 }
273
274 return [
275 'value' => $id,
276 'quantity_operator' => 'any',
277 'quantity_value1' => '1',
278 'quantity_value2' => '1'
279 ];
280 }, $rule['value']);
281 }
282 }
283
284 if (!$changed)
285 {
286 continue;
287 }
288
289 update_post_meta($box->ID, 'fpframework_meta_settings', wp_slash(json_decode(wp_json_encode($meta), true)));
290 }
291
292 $this->run = true;
293 }
294
295 /**
296 * Updates the Analytics Storage Period setting.
297 *
298 * @since 2.1.1
299 *
300 * @return void
301 */
302 public function updateAnalyticsStoragePeriodSetting()
303 {
304 if (version_compare($this->installedVersion, '2.1.1', '>='))
305 {
306 return;
307 }
308
309 $params = get_option('firebox_settings', []);
310
311 $statsdays = isset($params['statsdays']) ? $params['statsdays'] : 730;
312 $statsdays_custom = isset($params['statsdays_custom']) ? $params['statsdays_custom'] : false;
313
314 if ($statsdays === 'custom')
315 {
316 $statsdays = $statsdays_custom;
317 }
318
319 $statsdays = (int) $statsdays;
320
321 if ($statsdays <= 365)
322 {
323 $statsdays = 365;
324 }
325 else if ($statsdays <= 365 * 2)
326 {
327 $statsdays = 365 * 2;
328 }
329 else
330 {
331 $statsdays = 365 * 5;
332 }
333
334 $params['statsdays'] = $statsdays;
335
336 update_option('firebox_settings', $params);
337
338 $this->run = true;
339 }
340
341 public function update213version()
342 {
343 $this->updateLogsDetailsParamsColumn();
344 $this->moveFormConversionsToLogsDetailsTable();
345 }
346
347 /**
348 * Adds a new column called event_source after event column.
349 * Renames the params column in the logs details table to event_label.
350 *
351 * @since 2.1.4
352 *
353 * @return void
354 */
355 public function updateLogsDetailsParamsColumn()
356 {
357 if (version_compare($this->installedVersion, '2.1.4', '>='))
358 {
359 return;
360 }
361
362 global $wpdb;
363
364 // If has column params
365 $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'");
366 if (!$row)
367 {
368 $this->run = true;
369 return;
370 }
371
372 // Add column "event_source" after "event"
373 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD COLUMN `event_source` varchar(200) NOT NULL AFTER `event`");
374
375 // Rename params to event_label
376 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details CHANGE COLUMN `params` `event_label` text NOT NULL");
377
378 $this->run = true;
379 }
380
381 /**
382 * Moves form conversions from submission meta table to logs details table.
383 *
384 * @since 2.1.4
385 *
386 * @return void
387 */
388 private function moveFormConversionsToLogsDetailsTable()
389 {
390 if (version_compare($this->installedVersion, '2.1.4', '>='))
391 {
392 return;
393 }
394
395 global $wpdb;
396
397 // Get all submission meta data
398 $boxlogids = firebox()->tables->submissionmeta->getResults([
399 'select' => [
400 "{$wpdb->prefix}firebox_submission_meta.id",
401 'l.box',
402 's.form_id',
403 "{$wpdb->prefix}firebox_submission_meta.meta_value",
404 "{$wpdb->prefix}firebox_submission_meta.created_at"
405 ],
406 'where' => [
407 'meta_key' => " = '" . absint('box_log_id') . "'"
408 ],
409 'join' => [
410 "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",
411 ]
412 ]);
413
414 if (!$boxlogids)
415 {
416 $this->run = true;
417 return;
418 }
419
420 global $wpdb;
421
422 // Migrate to the box logs details table
423 foreach ($boxlogids as $row)
424 {
425 if (!$row->box)
426 {
427 continue;
428 }
429
430 $form = Form::getFormByID($row->form_id);
431
432 $data = [
433 'log_id' => $row->meta_value,
434 'event' => 'conversion',
435 'event_source' => 'form',
436 'event_label' => isset($form['block']['attrs']['formName']) ? $form['block']['attrs']['formName'] : 'FireBox #' . $row->box . ' Form',
437 'date' => $row->created_at
438 ];
439
440 firebox()->tables->boxlogdetails->insert($data);
441 }
442
443 // Delete all submission_meta rows
444 $ids = implode(',', array_map('intval', array_column($boxlogids, 'id')));
445 $sm_table_name = firebox()->tables->submissionmeta->getFullTableName();
446 $wpdb->query("DELETE FROM $sm_table_name WHERE id IN($ids)");// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
447
448 $this->run = true;
449 }
450
451 public function addMissingCapabilities()
452 {
453 if (version_compare($this->installedVersion, '2.1.15', '>='))
454 {
455 return;
456 }
457
458 $cap_name = 'read_fireboxes';
459
460 $admin = get_role('administrator');
461
462 if ($admin)
463 {
464 if ($admin->has_cap($cap_name))
465 {
466 return true;
467 }
468
469 $admin->add_cap($cap_name);
470 }
471 else
472 {
473 $roles = get_editable_roles();
474
475 foreach ($roles as $role_name => $data)
476 {
477 if (isset($data['capabilities']['manage_options']) && $data['capabilities']['manage_options'])
478 {
479 $role = get_role($role_name);
480
481 if (!$role)
482 {
483 continue;
484 }
485
486 if ($role->has_cap($cap_name))
487 {
488 continue;
489 }
490
491 $role->add_cap($cap_name);
492 }
493 }
494 }
495
496 wp_get_current_user()->get_role_caps();
497
498 return true;
499 }
500
501
502
503
504
505 /**
506 * Adds new indexes to the logs details table.
507 *
508 * @since 3.1.0
509 *
510 * @return void
511 */
512 private function addNewIndexes()
513 {
514 if (version_compare($this->installedVersion, '3.1.0', '>='))
515 {
516 return;
517 }
518
519 if (!$this->hasIndex('idx_firebox_logs_details_event_log', 'firebox_logs_details'))
520 {
521 global $wpdb;
522 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD INDEX `idx_firebox_logs_details_event_log` (`event`, `log_id`)");
523 }
524 if (!$this->hasIndex('idx_firebox_logs_details_event_source_log', 'firebox_logs_details'))
525 {
526 global $wpdb;
527 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD INDEX `idx_firebox_logs_details_event_source_log` (`event_source`, `log_id`)");
528 }
529 if (!$this->hasIndex('idx_firebox_logs_details_event_date', 'firebox_logs_details'))
530 {
531 global $wpdb;
532 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD INDEX `idx_firebox_logs_details_event_date` (`event`, `date`)");
533 }
534 if (!$this->hasIndex('idx_firebox_logs_details_event_source_event_log', 'firebox_logs_details'))
535 {
536 global $wpdb;
537 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD INDEX `idx_firebox_logs_details_event_source_event_log` (`event_source`, `event`, `log_id`)");
538 }
539 if (!$this->hasIndex('idx_firebox_logs_details_event_source_event_date', 'firebox_logs_details'))
540 {
541 global $wpdb;
542 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_logs_details ADD INDEX `idx_firebox_logs_details_event_source_event_date` (`event_source`, `event`, `date`)");
543 }
544
545 $this->run = true;
546 }
547
548 /**
549 * Checks whether an index exists in a table.
550 *
551 * @param string $index
552 * @param string $table
553 *
554 * @return bool
555 */
556 /**
557 * Adds missing indexes on the submissions tables to speed up
558 * form_id/state lookups and submission_id meta lookups.
559 *
560 * @since 3.1.9
561 *
562 * @return void
563 */
564 private function addSubmissionsIndexes()
565 {
566 if (version_compare($this->installedVersion, '3.1.9', '>='))
567 {
568 return;
569 }
570
571 if (!$this->hasIndex('idx_form_id_state', 'firebox_submissions'))
572 {
573 global $wpdb;
574 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_submissions ADD INDEX `idx_form_id_state` (`form_id`, `state`)");
575 }
576
577 if (!$this->hasIndex('idx_submission_id', 'firebox_submission_meta'))
578 {
579 global $wpdb;
580 $wpdb->query("ALTER TABLE {$wpdb->prefix}firebox_submission_meta ADD INDEX `idx_submission_id` (`submission_id`)");
581 }
582
583 $this->run = true;
584 }
585
586 private function hasIndex($index = '', $table = '')
587 {
588 if (empty($index) || empty($table))
589 {
590 return;
591 }
592
593 global $wpdb;
594
595 $existing = $wpdb->get_row("SHOW CREATE TABLE `{$wpdb->prefix}{$table}`", ARRAY_N);// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
596
597 if (isset($existing[1]) && strpos(strtolower($existing[1]), 'key `' . $index . '` (') !== false)
598 {
599 return true;
600 }
601
602 return false;
603 }
604 }
605