PluginProbe ʕ •ᴥ•ʔ
Brevo – Email, SMS, Web Push, Chat, and more. / 3.3.0
Brevo – Email, SMS, Web Push, Chat, and more. v3.3.0
2.9.13 2.9.14 2.9.15 2.9.16 2.9.17 2.9.18 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.9 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.2 3.1.20 3.1.21 3.1.22 3.1.23 3.1.24 3.1.25 3.1.26 3.1.27 3.1.28 3.1.29 3.1.3 3.1.30 3.1.31 3.1.32 3.1.33 3.1.34 3.1.35 3.1.36 3.1.37 3.1.38 3.1.39 3.1.4 3.1.40 3.1.41 3.1.42 3.1.43 3.1.44 3.1.45 3.1.46 3.1.47 3.1.48 3.1.49 3.1.5 3.1.50 3.1.51 3.1.52 3.1.53 3.1.54 3.1.55 3.1.56 3.1.57 3.1.58 3.1.59 3.1.6 3.1.60 3.1.61 3.1.62 3.1.63 3.1.64 3.1.65 3.1.66 3.1.67 3.1.68 3.1.69 3.1.7 3.1.70 3.1.71 3.1.72 3.1.73 3.1.74 3.1.75 3.1.76 3.1.77 3.1.78 3.1.79 3.1.8 3.1.80 3.1.81 3.1.82 3.1.83 3.1.84 3.1.85 3.1.86 3.1.87 3.1.88 3.1.89 3.1.9 3.1.90 3.1.91 3.1.92 3.1.93 3.1.94 3.1.95 3.1.96 3.1.97 3.1.98 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 trunk 1.0 1.5 2.0.8 2.9.10 2.9.11 2.9.12
mailin / inc / push-api.php
mailin / inc Last commit date
templates 1 year ago SendinblueAccount.php 1 year ago SendinblueApiClient.php 5 months ago function.wp_mail.php 8 years ago http-build-url.php 1 year ago index.php 8 years ago mailin.php 3 years ago push-admin.php 5 months ago push-amp.php 1 year ago push-api.php 5 months ago push-httpclient.php 1 year ago push-public.php 1 year ago push-settings.php 5 months ago push-utils.php 5 months ago push-woocommerce.php 11 months ago sendinblue.php 3 years ago sib-api-manager.php 1 year ago sib-form-preview.php 2 years ago sib-sms-code.php 5 months ago table-forms.php 1 year ago
push-api.php
534 lines
1 <?php
2 if (!defined( 'ABSPATH' )) { http_response_code(403); exit(); }
3
4 if ( ! class_exists( 'SIB_Push_API' ) ) {
5 class SIB_Push_API {
6
7 const NONCE_ACTION = 'ajax_sib_admin_nonce';
8 const ADMIN_ACCESS = 'admin';
9 const EDITOR_ACCESS = 'editor';
10 private static $nonce = null;
11
12 public static function init() {
13 add_action( 'wp_ajax_sib_get_push_configuration', array( 'SIB_Push_API', 'ajax_get_push_configuration' ) );
14 add_action( 'wp_ajax_sib_update_push_configuration', array( 'SIB_Push_API', 'ajax_update_push_configuration' ) );
15 add_action( 'wp_ajax_sib_push_get_post_metadata', array('SIB_Push_API', 'ajax_get_post_metadata'));
16 add_action( 'wp_ajax_sib_push_set_push_activated', array('SIB_Push_API', 'ajax_set_push_activated'));
17 add_action( 'wp_ajax_sib_push_management_api', array('SIB_Push_API', 'ajax_management_api'));
18 add_action( 'wp_ajax_sib_push_upload', array('SIB_Push_API', 'ajax_upload'));
19 add_action( 'wp_ajax_sib_push_force_create_cart_reminder_campaign', array('SIB_Push_API', 'ajax_force_create_cart_reminder_campaign'));
20 add_action('updated_option', array('SIB_Push_API', 'updated_option'), 10, 3);
21 self::prepare();
22 }
23
24 private static function prepare_cache_key() {
25 return 'sib_push_prepare_' . md5( SIB_Manager::$access_key );
26 }
27
28 private static function prepare() {
29 $settings = SIB_Push_Settings::getSettings();
30 $credentials = $settings->getWonderPushCredentials();
31 if (!$credentials) return;
32 try {
33 if ( !$settings->getShowPush() ) {
34 $settings->setShowPush ( SIB_Push_Utils::get_show_push() );
35 if ( $settings->getShowPush() ) $settings->save();
36 }
37 if ( get_transient( self::prepare_cache_key() ) === 'prepared' ) {
38 return;
39 }
40 set_transient( self::prepare_cache_key(), 'prepared', 86400 );
41 if ( SIB_Push_Utils::get_push_application() ) {
42 SIB_Push_Utils::update_settings();
43 return;
44 }
45 SIB_Push_Utils::create_push_application( 'prepare' );
46 $settings->save();
47 } catch ( \WonderPush\Errors\Server $e ) {
48 $code = $e->getResponse() ? $e->getResponse()->getStatusCode() : null;
49 if ( $code !== 429 ) {
50 SIB_Push_Utils::log_warn( 'Error creating application', $e );
51 } else {
52 // SIB_Push_Utils::log_debug( 'Refusing to create application', $e );
53 }
54 } catch ( SIB_Push_MissingCredentialsException $e) {
55 // Ignore
56 } catch ( Exception $e ) {
57 SIB_Push_Utils::log_debug('Error creating application', $e);
58 }
59 }
60
61 public static function updated_option($option, $old_value, $value) {
62 if ( $option === 'siteurl' && SIB_Push_Utils::get_push_application() ) {
63 // Site url's changed, bust prepare cache hoping that the next request will get the right plugin url
64 delete_transient( self::prepare_cache_key() );
65 }
66 }
67
68 public static function get_nonce() {
69 if (self::$nonce === null) self::$nonce = wp_create_nonce(self::NONCE_ACTION);
70 return self::$nonce;
71 }
72
73 private static function verify_nonce() {
74 $nonce = '';
75 if ($_SERVER['REQUEST_METHOD'] === 'POST') {
76 $nonce = $_POST['nonce'];
77 } else if ($_SERVER['REQUEST_METHOD'] === 'GET') {
78 $nonce = $_GET['nonce'];
79 }
80 if (!$nonce || !wp_verify_nonce($nonce, self::NONCE_ACTION)) {
81 wp_die('Forbidden', 403);
82 }
83 }
84
85 private static function verify_access($access_type = SIB_Push_API::ADMIN_ACCESS) {
86 self::verify_nonce();
87 if ($access_type === SIB_Push_API::EDITOR_ACCESS) {
88 if (!SIB_Push_Utils::can_send_notifications()) {
89 wp_die('Forbidden', 403);
90 }
91 } else {
92 if (!SIB_Push_Utils::can_modify_settings()) {
93 wp_die('Forbidden', 403);
94 }
95 }
96 }
97
98 private static function returnResult($result) {
99 header('Content-Type: application/json');
100 $json = json_encode($result);
101 echo $json;
102 wp_die();
103 }
104
105 private static function returnError($msg, $statusCode) {
106 header('Content-Type: application/json');
107 wp_die(json_encode(array(
108 'error' => array(
109 'message' => $msg,
110 'code' => $statusCode,
111 ),
112 )), $statusCode);
113 }
114
115 public static function ajax_upload() {
116 self::verify_access();
117 $settings = SIB_Push_Settings::getSettings();
118 $credentials = $settings->getWonderPushCredentials();
119 try {
120 $app = SIB_Push_Utils::get_push_application(SIB_Push_Utils::DEFAULT_CACHE_TTL);
121 } catch (Exception $e) {
122 SIB_Push_Utils::log_warn('Could not get application', $e);
123 self::returnError('Could not get application', 500);
124 }
125 $wp = SIB_Push_Utils::management_api_client($credentials);
126 $request = $wp->rest()->request('POST', 'applications/' . urlencode($app->getId()) . '/upload');
127 $image = $_FILES['image'];
128 if (!$image) {
129 self::returnError('Missing image', 400);
130 }
131 $request->addFile('image', $image['name'], $image['tmp_name'], $image['type']);
132 $response = $wp->rest()->execute($request);
133 $responseHeaders = $response->getHeaders();
134 if (isset($responseHeaders['content-type'])) {
135 header('Content-Type: ' . $responseHeaders['content-type']);
136 }
137 wp_die($response->getRawBody(), $response->getStatusCode());
138 }
139
140 public static function ajax_management_api() {
141 self::verify_access();
142 $method = isset($_POST['method']) ? $_POST['method'] : null;
143 $url = isset($_POST['url']) ? $_POST['url'] : null;
144 $body = isset($_POST['body']) ? wp_unslash($_POST['body']) : null;
145
146 switch ($method) {
147 case \WonderPush\Net\Request::GET:
148 case \WonderPush\Net\Request::PUT:
149 case \WonderPush\Net\Request::POST:
150 case \WonderPush\Net\Request::PATCH:
151 case \WonderPush\Net\Request::DELETE:
152 break;
153 default:
154 $method = null;
155 }
156 if (!$method || !$url) {
157 self::returnError('Missing method or url', 400);
158 }
159 $params = $body !== null ? json_decode($body, false) : array();
160 if (json_last_error()) {
161 self::returnError('Invalid JSON body', 400);
162 }
163
164 $settings = SIB_Push_Settings::getSettings();
165 $credentials = $settings->getWonderPushCredentials();
166
167 $wp = SIB_Push_Utils::management_api_client($credentials);
168
169 $request = $wp->rest()->request($method, '../../' . $url, $params);
170 $response = $wp->rest()->execute($request);
171 $responseHeaders = $response->getHeaders();
172 if (isset($responseHeaders['content-type'])) {
173 header('Content-Type: ' . $responseHeaders['content-type']);
174 }
175
176 // Intercept certain calls. We'll have to treat the special wonderpush/v1/batch as well
177 $reqsToCheck = array();
178 if ($method === 'POST' && $url === 'wonderpush/v1/batch' && isset($params->requests)) {
179 $reqsToCheck = array_map(function ($req) { return array($req->method, 'wonderpush'.$req->path); }, $params->requests);
180 } else {
181 $reqsToCheck = array(array($method, $url));
182 }
183
184 foreach ($reqsToCheck as $req) {
185 $reqMethod = $req[0];
186 $reqUrl = $req[1];
187 // Intercept cart reminder campaign update to clear the cache
188 // NOTE: deactivate woocommerce
189 $cartReminderCampaign = null;
190 // $cartReminderCampaign = SIB_Push_WooCommerce::ensure_cart_reminder_campaign_exists();
191 if ($cartReminderCampaign && ($reqMethod === 'PATCH' || $reqMethod === 'DELETE') && str_starts_with($reqUrl, 'wonderpush/v1/campaigns/'.$cartReminderCampaign->getId())) {
192 try {
193 // SIB_Push_Utils::log_debug('Clearing cart reminder cache');
194 SIB_Push_WooCommerce::clear_cart_reminder_campaign_cache();
195 } catch ( Exception $e ) {
196 SIB_Push_Utils::log_warn('Could not clear cart reminder cache', $e);
197 }
198 }
199
200 // Intercept application updates to clear the cache
201 if ($reqMethod === 'PATCH' && str_starts_with($reqUrl, 'wonderpush/v1/applications/')) {
202 $app = SIB_Push_Utils::get_push_application();
203 if ($app && $reqUrl === 'wonderpush/v1/applications/' . $app->getId()) {
204 try {
205 // SIB_Push_Utils::log_debug('Clearing application cache');
206 SIB_Push_Utils::clear_push_application_cache();
207 } catch ( Exception $e ) {
208 SIB_Push_Utils::log_warn('Could not clear application cache', $e);
209 }
210 }
211 }
212 }
213
214 wp_die($response->getRawBody(), $response->getStatusCode());
215 }
216
217 public static function ajax_set_push_activated() {
218 self::verify_access();
219 if (array_key_exists('activated', $_POST)) {
220 try {
221 $app = null;
222 if ($_POST['activated'] === 'true') {
223 $app = SIB_Push_Utils::activate_push();
224 if ($app && $app->getStatus() === 'creation') {
225 $app = SIB_Push_Utils::pollApplicationCreation();
226 }
227 } else {
228 SIB_Push_Utils::deactivate_push();
229 }
230 self::returnResult(array('application' => $app, 'configuration' => self::get_push_configuration()));
231 } catch (Exception $e) {
232 self::returnError($e->getMessage(), 500);
233 }
234 }
235 }
236
237 public static function get_push_configuration() {
238 $settings = SIB_Push_Settings::getSettings();
239 $app = SIB_Push_Utils::get_push_application();
240 return (object)array(
241 'applicationId' => $app && $app->getId() ? $app->getId() : null,
242 'websiteUrl' => get_site_url(),
243 'websiteName' => get_bloginfo('name'),
244 'pushOptions' => SIB_Push_Utils::wonderpush_init_options(),
245 'imgUrl' => plugins_url('img', dirname(__FILE__)),
246 'bypassWordPressHttpClient' => $settings->getBypassWordPressHttpClient(),
247 'deliveryTimeSeconds' => $settings->getDeliveryTimeSeconds(),
248 'notificationTitle' => $settings->getNotificationTitle(),
249 'defaultTargetSegmentId' => (int)$settings->getDefaultTargetSegmentId() ?: null,
250 'defaultTargetListId' => (int)$settings->getDefaultTargetListId() ?: null,
251 'additionalCustomPostTypes' => $settings->getAdditionalCustomPostTypes(),
252 'disableSendOnPublish' => $settings->getDisableSendOnPublish(),
253 'disableSendByDefaultOnPublish' => $settings->getDisableSendByDefaultOnPublish(),
254 'sendOnThirdPartyPublish' => $settings->getSendOnThirdPartyPublish(),
255 'disableFeedbackOnPublish' => $settings->getDisableFeedbackOnPublish(),
256 'disableUsePostImageForNotification' => $settings->getDisableUsePostImageForNotification(),
257 'preferLargeImageForNotification' => $settings->getPreferLargeImageForNotification(),
258 'cartReminderCampaignId' => $settings->getCartReminderCampaignId(),
259 'enableOrderCompleteNotifications' => $settings->getEnableOrderCompleteNotifications(),
260 'orderCompleteNotificationsMessage' => $settings->getOrderCompleteNotificationsMessage(),
261 'enableOrderProcessingNotifications' => $settings->getEnableOrderProcessingNotifications(),
262 'orderProcessingNotificationsMessage' => $settings->getOrderProcessingNotificationsMessage(),
263 'disableThankYouEvent' => $settings->getDisableThankYouEvent(),
264 'thankYouEventName' => $settings->getThankYouEventName(),
265 'disableAmpUnsubscribe' => $settings->getDisableAmpUnsubscribe(),
266 'ampSubscribeButtonLabel' => $settings->getAmpSubscribeButtonLabel(),
267 'ampUnsubscribeButtonLabel' => $settings->getAmpUnsubscribeButtonLabel(),
268 'disableAmpBottomSubscribeButton' => $settings->getDisableAmpBottomSubscribeButton(),
269 'disableAmpTopSubscribeButton' => $settings->getDisableAmpTopSubscribeButton(),
270 'ampButtonWidth' => (int)$settings->getAmpButtonWidth(),
271 'ampButtonHeight' => (int)$settings->getAmpButtonHeight(),
272 'additionalInitOptionsJson' => $settings->getAdditionalInitOptionsJson(),
273 'hideAdminBarShortcut' => $settings->getHideAdminBarShortcut(),
274 'sendOnlyToThisDomain' => $settings->getSendOnlyToThisDomain(),
275 );
276 }
277
278 public static function ajax_get_push_configuration() {
279 self::verify_access();
280 self::returnResult(self::get_push_configuration());
281 }
282
283 public static function ajax_update_push_configuration() {
284 self::verify_access();
285 $settings = SIB_Push_Settings::getSettings();
286 $save = false;
287 // Boolean props
288 foreach (array(
289 'bypassWordPressHttpClient',
290 'disableSendOnPublish',
291 'disableSendByDefaultOnPublish',
292 'sendOnThirdPartyPublish',
293 'disableFeedbackOnPublish',
294 'disableUsePostImageForNotification',
295 'preferLargeImageForNotification',
296 'enableOrderCompleteNotifications',
297 'enableOrderProcessingNotifications',
298 'disableAmpUnsubscribe',
299 'disableAmpBottomSubscribeButton',
300 'disableAmpTopSubscribeButton',
301 'disableThankYouEvent',
302 'hideAdminBarShortcut',
303 'sendOnlyToThisDomain',
304 ) as $key) {
305 if (array_key_exists($key, $_POST)) {
306 $settings->{"set" . ucfirst($key)}($_POST[$key] === 'true');
307 $save = true;
308 }
309 }
310 // Notification title
311 if (array_key_exists('notificationTitle', $_POST)) {
312
313 // Sanitize user input
314 $value = $_POST['notificationTitle']
315 ? stripslashes(trim(sanitize_text_field($_POST['notificationTitle']))) : '';
316
317 // Validate user input
318 $value = $value && strlen($value) > 1024 ? substr($value, 0, 1024) : $value;
319
320 $settings->setNotificationTitle($value);
321 $save = true;
322 }
323 // Default target segment ID
324 if (array_key_exists('defaultTargetSegmentId', $_POST)) {
325
326 // Sanitize user input
327 $value = $_POST['defaultTargetSegmentId']
328 ? (int)trim(sanitize_text_field($_POST['defaultTargetSegmentId'])) : null;
329
330 // Validate
331 $value = is_int($value) ? $value : null;
332
333 $settings->setDefaultTargetSegmentId($value);
334 $save = true;
335 }
336 // Default target list ID
337 if (array_key_exists('defaultTargetListId', $_POST)) {
338
339 // Sanitize user input
340 $value = $_POST['defaultTargetListId']
341 ? (int)trim(sanitize_text_field($_POST['defaultTargetListId'])) : null;
342
343 // Validate
344 $value = is_int($value) ? $value : null;
345
346 $settings->setDefaultTargetListId($value);
347 $save = true;
348 }
349 // Additional custom post types
350 if (array_key_exists('additionalCustomPostTypes', $_POST)) {
351
352 // Sanitize user input
353 $value = $_POST['additionalCustomPostTypes']
354 ? stripslashes(trim(sanitize_text_field($_POST['additionalCustomPostTypes']))) : '';
355
356 // Validate user input
357 $value = $value && strlen($value) > 1024 ? substr($value, 0, 1024) : $value;
358
359 $settings->setAdditionalCustomPostTypes($value);
360 $save = true;
361 }
362 // Order confirmation notifications message
363 if (array_key_exists('orderCompleteNotificationsMessage', $_POST)) {
364
365 // Sanitize user input
366 $value = $_POST['orderCompleteNotificationsMessage']
367 ? stripslashes(trim(sanitize_text_field($_POST['orderCompleteNotificationsMessage']))) : '';
368
369 // Validate user input
370 $value = $value && strlen($value) > 1024 ? substr($value, 0, 1024) : $value;
371
372 $settings->setOrderCompleteNotificationsMessage($value);
373 $save = true;
374 }
375 // Order confirmation notifications message
376 if (array_key_exists('orderProcessingNotificationsMessage', $_POST)) {
377 // Sanitize user input
378 $value = $_POST['orderProcessingNotificationsMessage']
379 ? stripslashes(trim(sanitize_text_field($_POST['orderProcessingNotificationsMessage']))) : '';
380
381 // Validate user input
382 $value = $value && strlen($value) > 1024 ? substr($value, 0, 1024) : $value;
383
384 $settings->setOrderProcessingNotificationsMessage($value);
385 $save = true;
386 }
387
388 // Thank you event name
389 if (array_key_exists('thankYouEventName', $_POST)) {
390 // Sanitize user input
391 $value = $_POST['thankYouEventName']
392 ? trim(sanitize_text_field($_POST['thankYouEventName'])) : '';
393
394 // Validate user input
395 $value = $value && strlen($value) > 256 ? substr($value, 0, 256) : $value;
396
397 $settings->setThankYouEventName($value);
398 $save = true;
399 }
400
401 // Additional init options
402 if (array_key_exists('additionalInitOptionsJson', $_POST)) {
403 // Sanitize user input
404 $value = $_POST['additionalInitOptionsJson']
405 ? stripslashes(trim(sanitize_text_field($_POST['additionalInitOptionsJson']))) : null;
406
407 // Validate user input
408 if ($value && strlen($value) > 2048) {
409 self::returnError(__('Additional init options JSON cannot be larger than 2048 bytes.'), 400);
410 return;
411 }
412 // Validate JSON
413 if ($value) {
414 $jsonValue = json_decode($value);
415 if (json_last_error()) {
416 self::returnError(__('Additional init options JSON must be valid JSON: ' + json_last_error_msg()), 400);
417
418 }
419 if (!is_object($jsonValue) && $jsonValue !== null) {
420 self::returnError(__('Additional init options JSON must be an object or null.'), 400);
421 return;
422 }
423 }
424 $value = $value ?: '';
425
426 $settings->setAdditionalInitOptionsJson($value);
427 $save = true;
428 }
429 // AMP Subscribe button label
430 if (array_key_exists('ampSubscribeButtonLabel', $_POST)) {
431 // Sanitize user input
432 $value = $_POST['ampSubscribeButtonLabel']
433 ? trim(sanitize_text_field($_POST['ampSubscribeButtonLabel'])) : '';
434
435 // Validate user input
436 $value = $value && strlen($value) > 1024 ? substr($value, 0, 1024) : $value;
437
438 $settings->setAmpSubscribeButtonLabel($value);
439 $save = true;
440 }
441 // AMP Unsubscribe button label
442 if (array_key_exists('ampUnsubscribeButtonLabel', $_POST)) {
443 // Sanitize user input
444 $value = $_POST['ampUnsubscribeButtonLabel']
445 ? trim(sanitize_text_field($_POST['ampUnsubscribeButtonLabel'])) : '';
446
447 // Validate user input
448 $value = $value && strlen($value) > 1024 ? substr($value, 0, 1024) : $value;
449
450 $settings->setAmpUnsubscribeButtonLabel($value);
451 $save = true;
452 }
453 // AMP Button width
454 if (array_key_exists('ampButtonWidth', $_POST)) {
455
456 // Sanitize
457 $value = $_POST['ampButtonWidth']
458 ? (int)trim(sanitize_text_field($_POST['ampButtonWidth'])) : null;
459
460 // Validate
461 $value = is_int($value) ? $value : null;
462
463 $settings->setAmpButtonWidth($value);
464 $save = true;
465 }
466 // AMP Button height
467 if (array_key_exists('ampButtonHeight', $_POST)) {
468
469 // Sanitize
470 $value = $_POST['ampButtonHeight']
471 ? (int)trim(sanitize_text_field($_POST['ampButtonHeight'])) : null;
472
473 // Validate
474 $value = is_int($value) ? $value : null;
475
476 $settings->setAmpButtonHeight($value);
477 $save = true;
478 }
479 // Delivery time seconds
480 if (array_key_exists('deliveryTimeSeconds', $_POST)) {
481
482 // Sanitize
483 $value = $_POST['deliveryTimeSeconds']
484 ? (int)trim(sanitize_text_field($_POST['deliveryTimeSeconds'])) : null;
485
486 // Validate
487 $value = is_int($value) ? $value : null;
488
489 $settings->setDeliveryTimeSeconds($value);
490 $save = true;
491 }
492 if ($save) $settings->save();
493 // NOTE: deactivate woocommerce
494 // SIB_Push_WooCommerce::ensure_cart_reminder_campaign_exists();
495 self::ajax_get_push_configuration();
496 }
497
498 public static function ajax_get_post_metadata() {
499 self::verify_access(SIB_Push_API::EDITOR_ACCESS);
500 $post_id = intval($_GET['post_id']);
501
502 if(is_null($post_id)){
503 self::returnError('Provide post_id query paramter', 400);
504 return;
505 }
506
507 $info = get_post_meta($post_id, SIB_Push_Admin::POST_META_INFO_MESSAGE);
508 if(is_array($info)){
509 $info = $info ? $info[0] : null;
510 }
511
512 $error = get_post_meta($post_id, SIB_Push_Admin::POST_META_ERROR_MESSAGE);
513 if(is_array($error)){
514 $error = $error ? $error[0] : null;
515 }
516
517 // reset meta
518 delete_post_meta($post_id, SIB_Push_Admin::POST_META_INFO_MESSAGE);
519 delete_post_meta($post_id, SIB_Push_Admin::POST_META_ERROR_MESSAGE);
520
521 self::returnResult((object)array('error_message' => $error, 'info_message' => $info));
522 }
523
524 public static function ajax_force_create_cart_reminder_campaign() {
525 self::verify_access();
526 if ($_SERVER['REQUEST_METHOD'] !== 'POST') self::returnError('Method not allowed', 405);
527 $campaign = SIB_Push_WooCommerce::ensure_cart_reminder_campaign_exists(true);
528 self::returnResult(array('success' => true, 'campaign' => $campaign->toData()));
529 }
530
531 }
532
533 }
534