PluginProbe
MyRewards / trunk
MyRewards vtrunk
5.7.8 5.7.7 5.7.6 trunk 1.2.2 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.1 2.2.0 2.3.0 2.4.0 2.4.1 2.5.0 2.6.4 2.6.6 3.0.0.0 3.1.0 3.1.2 3.1.2.1 3.10.4 3.10.9 All 165 releases
woorewards / include / updater.php

updater.php in MyRewards trunk, at include/updater.php

744 lines 26.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace LWS\WOOREWARDS;
3
4 // don't call the file directly
5 if( !defined( 'ABSPATH' ) ) exit();
6
7 /** satic class to manage activation and version updates. */
8 class Updater
9 {
10 private static $defaultStackId = 'default';
11
12 /** First use */
13 static function activate()
14 {
15 // repeated here since WooCommerce could be activated afterward
16 // and re-activate this will resolve WC role missing capacity problem
17 self::addCapacity();
18 }
19
20 static function checkUpdate()
21 {
22 $wpInstalling = \wp_installing();
23 \wp_installing(true); // should force no cache
24
25 $oldVersion = \get_option('lws_woorewards_version', '0');
26 if( version_compare($oldVersion, LWS_WOOREWARDS_VERSION, '<') )
27 {
28 \wp_suspend_cache_invalidation(false);
29 self::update($oldVersion, LWS_WOOREWARDS_VERSION);
30 update_option('lws_woorewards_version', LWS_WOOREWARDS_VERSION);
31 }
32
33 \wp_installing($wpInstalling);
34 }
35
36 /** Update
37 * @param $fromVersion previously registered version.
38 * @param $toVersion actual version. */
39 static function update($fromVersion, $toVersion)
40 {
41 global $wpdb;
42
43 $fresh = version_compare($fromVersion, '1.0.0', '<');
44
45 if( version_compare($fromVersion, '2.6.6', '<') )
46 {
47 self::addCapacity();
48 \update_option('lws_woorewards_redirect_to_licence', 1);
49 }
50
51 self::updateDatabaseTables();
52
53 if( version_compare($fromVersion, '3.0.0', '<') )
54 {
55 \wp_clear_scheduled_hook('lws_woorewards_coupon_reminder_event'); // replaced by 'lws_woorewards_daily_event'
56
57 if( !(defined('LWS_WIZARD_SUMMONER') && LWS_WIZARD_SUMMONER) )
58 self::addDefaultPools();
59
60 self::databaseMigrationv2v3();
61 self::optionMigrationv2v3();
62
63 // Convert each shop_order postmeta 'lws_woorewards_validate_order' to new event <once> mark
64 foreach( array('lws_woorewards_events_firstorder', 'lws_woorewards_events_orderamount', 'lws_woorewards_events_ordercompleted') as $meta ) {
65 // let as it is for hpos support, in a new install with WC 7.8+, we can expect a WR 5.0+ fresh install too.
66 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
67 $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) SELECT s.post_id, %s, s.meta_value FROM {$wpdb->postmeta} AS s WHERE s.meta_key='lws_woorewards_validate_order'", $meta));
68 }
69 }
70
71 if (\version_compare($fromVersion, '5.4.15', '<')) {
72 self::mergeAllHistorics();
73 }
74
75 if( version_compare($fromVersion, '3.13.2', '<') )
76 {
77 self::updateNamesWPML();
78 }
79
80 if( version_compare($fromVersion, '4.0.0', '<') )
81 {
82 self::updateProductReviewEvent(); // product review is now in free
83 self::updateDefaultPoolEvents();
84
85 \do_action('lws_adminpanel_licenses_migration', 'woorewards');
86
87 // badly named option mirgated from bool to list
88 $status = \get_option('lws_woorewards_points_distribution_status', false);
89 if( false === $status )
90 {
91 $status = array('processing', 'completed');
92 if( \get_option('lws_woorewards_coupon_state' , false) ) // checked: Points on 'Complete' order only
93 $status = array('completed');
94 \update_option('lws_woorewards_points_distribution_status', $status);
95 }
96
97 self::eventPoolNameToId();
98 }
99
100 // fresh install
101 if (!$fromVersion) {
102 if (false === \get_option('lws_woorewards_cart_content_side', false)) {
103 \update_option('lws_woorewards_cart_content_side', '<div class="cart-collaterals cross-sells">[wr_points_on_cart showall="yes"]</div>');
104 }
105 }
106
107 if (!\get_option('lws_woorewards_install_version')) {
108 if ($fromVersion && \version_compare($fromVersion, '1.0.0', '>')) {
109 // update (fromVersion greater than 0)
110 \update_option('lws_woorewards_install_version', '4.0.0');
111 } else {
112 // fresh install (from version is '0')
113 \update_option('lws_woorewards_install_version', LWS_WOOREWARDS_VERSION);
114 }
115 }
116
117 if ($fromVersion && \version_compare($fromVersion, '4.6.4', '<')) {
118 $couponPrefixLength = \get_option('lws_woorewards_coupon_code_length', false);
119 if (!$couponPrefixLength && (false !== $couponPrefixLength)) {
120 // saved but empty, previously give 8 (since default was 10)
121 \update_option('lws_woorewards_coupon_code_length', 8);
122 }
123 }
124
125 if ($fromVersion && \version_compare($fromVersion, '1.0.0', '>') && \version_compare($fromVersion, '4.9.1', '<')) {
126 self::setOldMailEnabledDefaultValue();
127 }
128
129 if ($fromVersion && \version_compare($fromVersion, '5.0.0', '<')) {
130 // moved from pro
131 $type = array(
132 'lws_woorewards_pro_events_sponsoredorderamount' => 'lws_woorewards_events_sponsoredorderamount',
133 'lws_woorewards_pro_events_sponsoredfirstorder' => 'lws_woorewards_events_sponsoredorder',
134 );
135 foreach ($type as $src => $dst) {
136 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
137 $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value=%s WHERE meta_key='wre_event_type' AND meta_value=%s", $dst, $src));
138 }
139 self::addV5PrefabEvents();
140 }
141
142 if (!$fresh && version_compare($fromVersion, '5.6.0', '<')) {
143 self::v560();
144 }
145
146 $defaultOptions = array(
147 'lws_woorewards_show_loading_order_and_priority' => '',
148 'lws_woorewards_hide_internal_meta' => 'on',
149 'lws_woorewards_event_enabled_sponsorship' => 'on',
150 'lws_woorewards_referral_back_give_sponsorship' => 'on',
151 'lws_woorewards_sponsorship_tinify_enabled' => '',
152 'lws_woorewards_sponsorship_short_url' => '',
153 'lws_woorewards_points_distribution_status' => array('processing', 'completed'),
154 );
155 foreach ($defaultOptions as $optName => $optValue) {
156 if (false === \get_option($optName, false)) {
157 \update_option($optName, $optValue);
158 }
159 }
160
161 // woorewards is based on woocommerce coupons, so enable them
162 \update_option('woocommerce_enable_coupons', 'yes');
163 \update_option('lws_woorewards_ignore_woocommerce_disable_coupons', '');
164 }
165
166 public static function v560()
167 {
168 $option = 'lws_woorewards_history_template';
169 $css64 = \get_option($option, false);
170 if ($css64) {
171 $css = \base64_decode($css64);
172 $file = LWS_WOOREWARDS_PATH . '/styling/css/templates/userpointshistory.css';
173 global $wp_filesystem;
174 if ( empty( $wp_filesystem ) ) {
175 require_once ABSPATH . '/wp-admin/includes/file.php';
176 \WP_Filesystem();
177 }
178 $content = $wp_filesystem->get_contents( $file );
179 if ($content) {
180 \update_option($option, \base64_encode($content . "\n\n" . $css));
181
182 // revoke cache
183 $cacheName = sanitize_key($option) . '-cached.css';
184 $cached = new \LWS\Adminpanel\Tools\Cache($cacheName);
185 $cached->del();
186 \update_option($option . '_adm_ts', time());
187 }
188 }
189 }
190
191 /** @retrun bool merge done successfully */
192 public static function mergeAllHistorics(): bool
193 {
194 if (!\is_multisite()) return true;
195
196 global $wpdb;
197 // only do it once on main site
198 if ($wpdb->base_prefix !== $wpdb->prefix) return false;
199
200 $target = $wpdb->base_prefix . 'lws_wr_historic';
201 $sources = \array_diff(
202 (array) $wpdb->get_col("SHOW TABLES LIKE '%lws_wr_historic'"), // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
203 [$target]
204 );
205 if (!$sources) return true;
206
207 try {
208 // try to give 5min to let db copy under IIS servers,
209 // others do not take into account time spent outside the script itself
210 @\set_time_limit(5 * 60); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- migration needs time
211 } catch (\Exception $_e) {}
212
213 // compose the query
214 $query = \implode(';', \array_map(function($table) use ($target) {
215 $fields = '`user_id`, `stack`, `mvt_date`, `points_moved`, `new_total`, `commentar`, `origin`, `origin2`, `order_id`, `blog_id`';
216 return sprintf(
217 'INSERT INTO `%s` (%s) SELECT %s FROM `%s`',
218 $target,
219 $fields,
220 $fields,
221 $table
222 );
223 }, $sources));
224
225 // merge all history into main one
226 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- migration query with table names
227 $done = (bool)$wpdb->query($query);
228
229 if ($done) {
230 // prevent lines duplication
231 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- migration TRUNCATE with escaped table names
232 $wpdb->query( \implode( ';', \array_map( function ( $table ) {
233 return sprintf( 'TRUNCATE `%s`', \esc_sql($table) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
234 }, $sources ) ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
235 }
236
237 return $done;
238 }
239
240 /** keep old default value since it became Off by default */
241 private static function setOldMailEnabledDefaultValue()
242 {
243 $enabledMails = array(
244 'wr_new_reward' => 'on',
245 'wr_achieved' => 'on',
246 'wr_available_unlockables' => 'on',
247 );
248 foreach ($enabledMails as $template => $value) {
249 if (false === \get_option('lws_woorewards_enabled_mail_' . $template, false)) {
250 \update_option('lws_woorewards_enabled_mail_' . $template, $value);
251 }
252 }
253 }
254
255 private static function eventPoolNameToId()
256 {
257 global $wpdb;
258 $sql = "SELECT p.post_name, m.post_id"
259 . " FROM {$wpdb->postmeta} as m"
260 . " INNER JOIN {$wpdb->posts} as e ON m.post_id=e.ID"
261 . " INNER JOIN {$wpdb->posts} as p ON p.ID=e.post_parent"
262 . " WHERE m.`meta_key`='wre_event_type'"
263 . " AND m.`meta_value` = 'lws_woorewards_events_productreview'";
264 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- migration query
265 $events = $wpdb->get_results($sql);
266 foreach( $events as $event )
267 {
268 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
269 $wpdb->query($wpdb->prepare(
270 "UPDATE {$wpdb->usermeta} SET `meta_key`=%s WHERE `meta_key`=%s",
271 'lws_wre_event_review_' . $event->post_id,
272 'lws_wre_event_review_' . $event->post_name
273 ));
274 }
275 }
276
277 public static function log($msg)
278 {
279 if( !empty($msg) )
280 error_log($msg); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- updater logging
281 }
282
283 private static function updateProductReviewEvent()
284 {
285 global $wpdb;
286 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
287 $wpdb->query("UPDATE {$wpdb->postmeta} SET meta_value = 'lws_woorewards_events_productreview' WHERE meta_value = 'lws_woorewards_pro_events_productreview'");
288 }
289
290 private static function updateDefaultPoolEvents()
291 {
292 $pools = self::loadStandardPool(true);
293 if( $pools->count() <= 0 )
294 return;
295 $pool = $pools->get(0);
296 if( 1 != $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_productreview';})->count() )
297 {
298 require_once LWS_WOOREWARDS_INCLUDES.'/events/productreview.php';
299 $event = new \LWS\WOOREWARDS\Events\ProductReview();
300 $pool->addEvent($event, 0);
301 $pool->save();
302 }
303 }
304
305 private static function updateDatabaseTables()
306 {
307 global $wpdb;
308 /// Alter table historic: Add stack field
309 $thistoric = $wpdb->base_prefix . 'lws_wr_historic';
310 $charset_collate = $wpdb->get_charset_collate();
311 $sql = "CREATE TABLE $thistoric (
312 id bigint(20) NOT NULL AUTO_INCREMENT,
313 user_id bigint(20) NOT NULL,
314 stack varchar(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT 'Each pool can have its own or share point stack',
315 mvt_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
316 points_moved int(10) NULL DEFAULT NULL,
317 new_total int(20) NULL DEFAULT NULL,
318 commentar text NOT NULL,
319 `origin` tinytext NULL COMMENT 'eg. unlockable/event post id (max 255 char)',
320 `origin2` bigint(20) NOT NULL DEFAULT 0 COMMENT 'Additionnal info. eg. user_id that trigger the event origin',
321 `order_id` INT(20) NULL DEFAULT NULL COMMENT 'If about a wc_order = post.ID',
322 `blog_id` INT(20) NULL DEFAULT NULL COMMENT 'For multisite, the current blog during operation',
323 PRIMARY KEY id (id),
324 KEY `user_id` (`user_id`),
325 KEY `stack` (`stack`)
326 ) $charset_collate;";
327
328 $tSuccess = $wpdb->prefix . 'lws_wr_achieved_log';
329 $sqlAchieved = "CREATE TABLE $tSuccess (
330 `id` bigint(30) NOT NULL AUTO_INCREMENT,
331 `user_id` bigint(20) NOT NULL COMMENT 'recipient user id',
332 `creation` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
333 `display` TIMESTAMP NULL DEFAULT NULL,
334 `popup` int(1) NOT NULL DEFAULT 1 COMMENT 'Is the achievement must pop to the user page or (false) only for log purpose',
335 `title` text NOT NULL,
336 `message` text NOT NULL,
337 `image` text NOT NULL COMMENT 'Achievement icon, if no url given, a default image is picked',
338 `background` text NOT NULL COMMENT 'Achievement icon background, if no url given, a default image is picked',
339 `badge_id` bigint(20) NULL DEFAULT NULL COMMENT 'The source badge if any',
340 `origin` tinytext NOT NULL COMMENT 'source of the achievement',
341 PRIMARY KEY id (id),
342 KEY `user_id` (`user_id`),
343 KEY `display` (`display`)
344 ) $charset_collate;";
345
346 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
347 ob_start(array(__CLASS__, 'log')); // dbDelta could write on standard output
348 dbDelta( $sql );
349 dbDelta( $sqlAchieved );
350 ob_end_flush();
351 }
352
353 /** Point history table migration. */
354 private static function databaseMigrationv2v3()
355 {
356 global $wpdb;
357 $thistoric = $wpdb->base_prefix . 'lws_wr_historic';
358
359 $default = !empty(self::$defaultStackId) ? self::$defaultStackId : 'default';
360
361 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- migration
362 $wpdb->query("ALTER TABLE {$thistoric} CHANGE points_moved points_moved SMALLINT(10) NULL DEFAULT NULL;");
363 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- migration
364 $wpdb->query($wpdb->prepare("UPDATE {$thistoric} SET stack=%s WHERE stack=''", $default));
365
366 $tmeta = $wpdb->usermeta;
367 $mkey = \LWS\WOOREWARDS\Core\PointStack::MetaPrefix;
368 // this query only works on MySql, we should only update last entry per user but it is ok like this
369 $copyPts = "UPDATE $thistoric INNER JOIN $tmeta ON $thistoric.user_id=$tmeta.user_id AND $tmeta.meta_key='lws_wr_points' SET new_total=$tmeta.meta_value";
370 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- migration
371 if( false !== $wpdb->query($copyPts) )
372 {
373 // point usermeta key renamed
374 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
375 $wpdb->query($wpdb->prepare("UPDATE {$tmeta} SET meta_key=%s WHERE meta_key='lws_wr_points'", $mkey . $default));
376 }
377 }
378
379 private static function optionMigrationv2v3()
380 {
381 // mail common settings
382 $prefix = 'lws_mail_'.'woorewards'.'_attribute_';
383 \add_option($prefix.'headerpic', \get_option('lws_woorewards_mail_attribute_headerpic', ''));
384 \add_option($prefix.'footer', \get_option('lws_woorewards_mail_attribute_footertext', ''));
385
386 // mail 'wr_new_reward'
387 $suffix = 'wr_new_reward';
388 \add_option('lws_mail_subject_' .$suffix, \get_option('lws_woorewards_mail_subject_newcoupon', ''));
389 \add_option('lws_mail_title_' .$suffix, \get_option('lws_woorewards_mail_title_newcoupon', ''));
390 \add_option('lws_mail_header_' .$suffix, \get_option('lws_woorewards_mail_header_newcoupon', ''));
391 \add_option('lws_mail_template_'.$suffix, \get_option('lws_woorewards_mail_template_newcoupon', ''));
392 }
393
394 /** Add 'manage_rewards' capacity to 'administrator' and 'shop_manager'. */
395 private static function addCapacity()
396 {
397 $cap = 'manage_rewards';
398 foreach( array('administrator', 'shop_manager') as $slug )
399 {
400 $role = \get_role($slug);
401 if( !empty($role) && !$role->has_cap($cap) )
402 {
403 $role->add_cap($cap);
404 }
405 }
406 }
407
408 /** Add pool "loyalty system -> standard" */
409 public static function addDefaultPools()
410 {
411 $pools = self::loadStandardPool(false);
412
413 if( $pools->count() <= 0 )
414 {
415 $name = 'default';
416 if( \is_multisite() )
417 $name .= \get_current_blog_id();
418 // create the default pool for free version
419 $pool = $pools->create($name)->last();
420 $pool->setOptions(array(
421 'type' => \LWS\WOOREWARDS\Core\Pool::T_STANDARD,
422 'disabled' => true,
423 'title' => "Standard System",
424 'whitelist' => array(\LWS\WOOREWARDS\Core\Pool::T_STANDARD)
425 ));
426
427 // order amount
428 require_once LWS_WOOREWARDS_INCLUDES.'/events/orderamount.php';
429 $event = new \LWS\WOOREWARDS\Events\OrderAmount();
430 $event->setDenominator(\get_option('lws_woorewards_value', 1));
431 $pool->addEvent($event, intval(\get_option('lws_woorewards_points', 0)));
432
433 // order completed
434 require_once LWS_WOOREWARDS_INCLUDES.'/events/ordercompleted.php';
435 $event = new \LWS\WOOREWARDS\Events\OrderCompleted();
436 $pool->addEvent($event, intval(\get_option('lws_woorewards_rewards_orders', 0)));
437 // first order
438 require_once LWS_WOOREWARDS_INCLUDES.'/events/firstorder.php';
439 $event = new \LWS\WOOREWARDS\Events\FirstOrder();
440 $pool->addEvent($event, intval(\get_option('lws_woorewards_rewards_orders_first', 0)));
441 // product review
442 require_once LWS_WOOREWARDS_INCLUDES.'/events/productreview.php';
443 $event = new \LWS\WOOREWARDS\Events\ProductReview();
444 $pool->addEvent($event, 0);
445
446 // coupon
447 require_once LWS_WOOREWARDS_INCLUDES.'/unlockables/coupon.php';
448 $coupon = new \LWS\WOOREWARDS\Unlockables\Coupon();
449 $coupon->setValue(\get_option('lws_woorewards_value_coupon', ''));
450 $coupon->setTimeout(\get_option('lws_woorewards_expiry_days', ''));
451 $pool->addUnlockable($coupon, intval(\get_option('lws_woorewards_stage', 0)));
452
453 if( $fromV2 = (false !== \get_option('lws_woorewards_value', false)) )
454 $pool->setOption('public', \LWS\Adminpanel\Tools\Conveniences::isWC());
455
456 $pool->save();
457 if( !empty($pool->getId()) ) // not deletable
458 {
459 \clean_post_cache($pool->getId());
460 \update_post_meta($pool->getId(), 'wre_pool_prefab', 'yes');
461 \update_option('lws_wr_default_pool_name', $pool->getName());
462 self::$defaultStackId = $pool->getStackId();
463
464 if($fromV2)
465 {
466 // remove outdated settings
467 \delete_option('lws_woorewards_points');
468 \delete_option('lws_woorewards_value');
469 \delete_option('lws_woorewards_rewards_orders');
470 \delete_option('lws_woorewards_rewards_orders_first');
471 \delete_option('lws_woorewards_value_coupon');
472 \delete_option('lws_woorewards_expiry_days');
473 \delete_option('lws_woorewards_stage');
474 }
475 }
476
477 if($fromV2)
478 {
479 \lws_admin_add_notice(
480 'up-lws-v2-settings',
481 "Your settings have been migrated during MyRewards update.
482 We tried our best to conserve the same behavior as before but we advise you to check them anyway.",
483 array(
484 'level' => 'success',
485 'once' => false,
486 'forgettable' => true
487 )
488 );
489 }
490 }
491 }
492
493 /** Could be on purpose after a downgrade from trial to free version. */
494 public static function isMissingPrefabEventsAndUnlockables()
495 {
496 $pools = self::loadStandardPool(true);
497 if( $pools->count() <= 0 )
498 return true;
499 $pool = $pools->get(0);
500 if( 1 != $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_orderamount';})->count() )
501 return true;
502 if( 1 != $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_ordercompleted';})->count() )
503 return true;
504 if( 1 != $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_firstorder';})->count() )
505 return true;
506 if( 1 != $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_productreview';})->count() )
507 return true;
508 if( 1 != $pool->getUnlockables()->filter(function($item){return $item->getType() == 'lws_woorewards_unlockables_coupon';})->count() )
509 return true;
510 return false;
511 }
512
513 /** @return bool dirty status (if something changed in pool) */
514 public static function addV5PrefabEvents($pool=false, $saveIfDirty=true)
515 {
516 $dirty = false;
517 if (!$pool) {
518 $pools = self::loadStandardPool(true);
519 if ($pools->count())
520 $pool = $pools->get(0);
521 }
522
523 if ($pool) {
524
525 $e = $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_sponsoredorderamount';});
526 if ($e->count() <= 0) {
527 require_once LWS_WOOREWARDS_INCLUDES . '/events/sponsoredorderamount.php';
528 $event = new \LWS\WOOREWARDS\Events\SponsoredOrderAmount();
529 $pool->addEvent($event, 0);
530 $dirty = true;
531 }
532
533 $e = $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_sponsoredorder';});
534 if ($e->count() <= 0) {
535 require_once LWS_WOOREWARDS_INCLUDES . '/events/sponsoredorder.php';
536 $event = new \LWS\WOOREWARDS\Events\SponsoredOrder();
537 $event->setFirstOrderOnly(false);
538 $pool->addEvent($event, 0);
539 $dirty = true;
540 }
541
542 if ($dirty && $saveIfDirty) {
543 $pool->save();
544 }
545 }
546 return $dirty;
547 }
548
549 /** Look at pool prefabs type='standard',
550 * add missing orderCompleted, firstOrder, OrderAmount and Coupon.
551 *
552 * Could be on purpose after a downgrade from trial to free version. */
553 public static function addMissingPrefabEventsAndUnlockables()
554 {
555 $pools = self::loadStandardPool(true);
556 if( $pools->count() <= 0 )
557 {
558 self::addDefaultPools();
559 }
560 else
561 {
562 $pool = $pools->get(0);
563 $dirty = false;
564
565 $e = $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_orderamount';});
566 while( $e->count() > 1 )
567 {
568 $item = $e->last();
569 $e->remove($item);
570 $pool->removeEvent($item);
571 $item->delete();
572 }
573 if( $e->count() <= 0 )
574 {
575 require_once LWS_WOOREWARDS_INCLUDES.'/events/orderamount.php';
576 $event = new \LWS\WOOREWARDS\Events\OrderAmount();
577 $pool->addEvent($event, 0);
578 $dirty = true;
579 }
580
581 $e = $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_ordercompleted';});
582 while( $e->count() > 1 )
583 {
584 $item = $e->last();
585 $e->remove($item);
586 $pool->removeEvent($item);
587 $item->delete();
588 }
589 if( $e->count() <= 0 )
590 {
591 require_once LWS_WOOREWARDS_INCLUDES.'/events/ordercompleted.php';
592 $pool->addEvent(new \LWS\WOOREWARDS\Events\OrderCompleted(), 0);
593 $dirty = true;
594 }
595
596 $e = $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_firstorder';});
597 while( $e->count() > 1 )
598 {
599 $item = $e->last();
600 $e->remove($item);
601 $pool->removeEvent($item);
602 $item->delete();
603 }
604 if( $e->count() <= 0 )
605 {
606 require_once LWS_WOOREWARDS_INCLUDES.'/events/firstorder.php';
607 $pool->addEvent(new \LWS\WOOREWARDS\Events\FirstOrder(), 0);
608 $dirty = true;
609 }
610
611 $e = $pool->getEvents()->filter(function($item){return $item->getType() == 'lws_woorewards_events_productreview';});
612 while( $e->count() > 1 )
613 {
614 $item = $e->last();
615 $e->remove($item);
616 $pool->removeEvent($item);
617 $item->delete();
618 }
619 if( $e->count() <= 0 )
620 {
621 require_once LWS_WOOREWARDS_INCLUDES.'/events/productreview.php';
622 $pool->addEvent(new \LWS\WOOREWARDS\Events\ProductReview(), 0);
623 $dirty = true;
624 }
625
626 $u = $pool->getUnlockables()->filter(function($item){return $item->getType() == 'lws_woorewards_unlockables_coupon';});
627 while( $e->count() > 1 )
628 {
629 $item = $u->last();
630 $u->remove($item);
631 $pool->removeUnlockable($item);
632 $item->delete();
633 }
634 if( $u->count() <= 0 )
635 {
636 require_once LWS_WOOREWARDS_INCLUDES.'/unlockables/coupon.php';
637 $pool->addUnlockable(new \LWS\WOOREWARDS\Unlockables\Coupon(), 0);
638 $dirty = true;
639 }
640 if (self::addV5PrefabEvents($pool, false)) {
641 $dirty = true;
642 }
643
644 if( $dirty )
645 {
646 $pool->save();
647 }
648 }
649 }
650
651 /** @return \LWS\WOOREWARDS\Collections\Pools pool collection */
652 protected static function loadStandardPool($deep=false)
653 {
654 // if not already exists (prefabs are not deletable)
655 $pools = \LWS\WOOREWARDS\Collections\Pools::instanciate()->load(array(
656 'numberposts' => 1,
657 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
658 array(
659 'key' => 'wre_pool_prefab',
660 'value' => 'yes', // This cannot be empty because of a bug in WordPress
661 'compare' => 'LIKE'
662 ),
663 array(
664 'key' => 'wre_pool_type',
665 'value' => \LWS\WOOREWARDS\Core\Pool::T_STANDARD,
666 'compare' => 'LIKE'
667 )
668 ),
669 'deep' => $deep
670 ));
671 return $pools;
672 }
673
674 protected static function updateNamesWPML()
675 {
676 global $wpdb;
677 $icl = $wpdb->prefix . 'icl_strings';
678
679 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- table name from wpdb prefix
680 if( $wpdb->get_col("SHOW TABLES LIKE '{$icl}'") )
681 {
682 $template = 'Woorewards mail - %s - %s';
683 $suffixes = array('Subject', 'Preheader', 'Title', 'Header');
684 $strings = array(
685 "New Reward" => array(
686 "Nouvelle récompense",
687 "Nueva recompensa",
688 "Neue Belohnung",
689 "Uusi palkkio",
690 "新的奖励",
691 ),
692 "Achievement" => array(
693 "Succès",
694 "Erfolg",
695 "成就",
696 "Logros",
697 ),
698 "Sponsorship" => array(
699 "Patrocinio",
700 "引荐",
701 "Parrainage",
702 "Sponsorointi",
703 ),
704 "Reward Choice" => array(
705 "Eleccion de recompensa",
706 "可选奖励",
707 "Belohnungsauswahl",
708 "Choix de récompense",
709 "Palkinnon valinta",
710 ),
711 "Expiry Reminder" => array(
712 "Recordatorio de caducidad",
713 "过期提示",
714 "Erinnerung für Verfallsdatum",
715 "Rappel d'expiration",
716 "Päättymisen muistutin",
717 ),
718 "Points Expiry Reminder" => array(
719 "Recordatorio de caducidad de puntos",
720 "积分过期提醒",
721 "Erinnerung für Punkteverfall",
722 "Rappel d’expiration de points",
723 "Päättymisen muistutin",
724 ),
725 );
726
727 foreach( $suffixes as $suffix )
728 {
729 foreach( $strings as $dst => $src )
730 {
731 $where = array();
732 foreach( $src as $trad )
733 $where[] = $wpdb->prepare('`name`=%s', sprintf($template, $trad, $suffix)); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
734
735 $sql = sprintf(
736 "UPDATE `{$icl}` SET `name`='{$template}' WHERE %s",
737 $dst, $suffix, implode(' OR ', $where)
738 );
739 $wpdb->query($sql); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- WPML migration with esc_sql'd table
740 }
741 }
742 }
743 }
744 }