PluginProbe
Brevo – Email, SMS, Web Push, Chat, and more. / 3.1.95
Brevo – Email, SMS, Web Push, Chat, and more. v3.1.95
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 All 140 releases
mailin / sendinblue.php
sendinblue.php
1,802 lines 62.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Newsletter, SMTP, Email marketing and Subscribe forms by Brevo
4 * Plugin URI: https://www.brevo.com/?r=wporg
5 * Description: Manage your contact lists, subscription forms and all email and marketing-related topics from your wp panel, within one single plugin
6 * Version: 3.1.95
7 * Author: Brevo
8 * Author URI: https://www.brevo.com/?r=wporg
9 * License: GPLv2 or later
10 *
11 * @package SIB
12 */
13
14 /*
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License
17 as published by the Free Software Foundation; either version 2
18 of the License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27
28 /**
29 * Application entry point. Contains plugin startup class that loads on <i> sendinblue_init </i> action.
30 */
31 if ( ! class_exists( 'Mailin' ) ) {
32 require_once( 'inc/mailin.php' );
33 }
34 if ( ! class_exists( 'SendinblueApiClient' ) ) {
35 require_once( 'inc/SendinblueApiClient.php' );
36 }
37 if ( ! class_exists( 'SendinblueAccount' ) ) {
38 require_once( 'inc/SendinblueAccount.php' );
39 }
40 // For marketing automation.
41 if ( ! class_exists( 'Sendinblue' ) ) {
42 require_once( 'inc/sendinblue.php' );
43 }
44
45 if ( ! class_exists( 'SIB_Manager' ) ) {
46 register_deactivation_hook( __FILE__, array( 'SIB_Manager', 'deactivate' ) );
47 register_activation_hook( __FILE__, array( 'SIB_Manager', 'install' ) );
48 register_uninstall_hook( __FILE__, array( 'SIB_Manager', 'uninstall' ) );
49
50 require_once( 'page/page-home.php' );
51 require_once( 'page/page-form.php' );
52 require_once( 'page/page-statistics.php' );
53 require_once( 'widget/widget_form.php' );
54 require_once( 'inc/table-forms.php' );
55 require_once( 'inc/sib-api-manager.php' );
56 require_once( 'inc/sib-sms-code.php' );
57 require_once( 'model/model-forms.php' );
58 require_once( 'model/model-users.php' );
59 require_once( 'model/model-lang.php' );
60 require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
61 require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
62 /**
63 * Class SIB_Manager
64 */
65 class SIB_Manager {
66
67 private const ROUTE_METHODS = 'methods';
68 private const ROUTE_CALLBACK = 'callback';
69 private const PERMISSION_CALLBACK = 'permission_callback';
70
71 /** Main setting option name */
72 const MAIN_OPTION_NAME = 'sib_main_option';
73
74 /** Home setting option name */
75 const HOME_OPTION_NAME = 'sib_home_option';
76
77 /** Access token option name */
78 const ACCESS_TOKEN_OPTION_NAME = 'sib_token_store';
79
80 /** Plugin language notice option name */
81 const LANGUAGE_OPTION_NAME = 'sib_language_notice_option';
82
83 /** Form preview option name */
84 const PREVIEW_OPTION_NAME = 'sib_preview_form';
85
86 const API_KEY_V3_OPTION_NAME = 'sib_api_key_v3';
87
88 const RECAPTCHA_API_TEMPLATE = 'https://www.google.com/recaptcha/api/siteverify?%s';
89
90 const TURNSTILE_SITE_VERIFY = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
91
92 /** Installation id option name */
93 const INSTALLATION_ID = 'sib_installation_id';
94 const BREVO_PLUGIN_VERSION = 'brevo_plugin_version';
95
96 /*Pushowl Url */
97 const PUSHOWL_STAGING_URL = "https://cdn-staging.pushowl.com/latest/sdks/service-worker.js";
98 const PUSHOWL_PRODUCTION_URL = "https://cdn.pushowl.com/latest/sdks/service-worker.js";
99 const URL_CHECK_STAGING = "staging";
100 const SERVICE_WORKER_FILE_URL = "/js/service-worker.js";
101
102 const SIB_ATTRIBUTE = array(
103 'input' => array(
104 'type' => true,
105 'name' => true,
106 'value' => true,
107 'class' => true,
108 'id' => true,
109 'size' => true,
110 'min' => true,
111 'max' => true,
112 'pattern' => true,
113 'title' => true,
114 'placeholder' => true,
115 'required' => true,
116 ),
117 'p' => array(
118 'align' => true,
119 'id' => true,
120 'class' => true,
121 'dir' => true,
122 'lang' => true,
123 'style' => true,
124 'xml:lang' => true,
125 ),
126 'iframe' => array(
127 'name' => true,
128 'id' => true,
129 'class' => true,
130 'src' => true,
131 'width' => true,
132 'height' => true,
133 'style' => true,
134 'loading' => true,
135 'allow' => true,
136 'allowfullscreen' => true,
137 ),
138 'div' => array(
139 'id' => true,
140 'class' => true,
141 'dir' => true,
142 'lang' => true,
143 'style' => true,
144 'xml:lang' => true,
145 'data-require' => true,
146 'data-sitekey' => true,
147 'data-error-callback' => true,
148 'data-theme' => true,
149 ),
150 'a' => array(
151 'href' => true,
152 'id' => true,
153 'class' => true,
154 'rel' => true,
155 'rev' => true,
156 'name' => true,
157 'target' => true,
158 ),
159 'style' => array(),
160 'script' => array(
161 'src' => true,
162 ),
163 'link' => array(
164 'rel' => true,
165 'href' => true,
166 'type' => true,
167 ),
168 'select' => array(
169 'name' => true,
170 'class' => true,
171 'id' => true,
172 'style' => true,
173 'required' => true,
174 ),
175 'option' => array(
176 'value' => true,
177 ),
178 'ul' => array(
179 'class' => true,
180 'style' => true,
181 ),
182 'center' => array(),
183 'download' => array(
184 'valueless' => 'y',
185 )
186 );
187
188 /**
189 * API key
190 *
191 * @var $access_key
192 */
193 public static $access_key;
194
195 /**
196 * Store instance
197 *
198 * @var $instance
199 */
200 public static $instance;
201
202 /**
203 * Plugin directory path value. set in constructor
204 *
205 * @var $plugin_dir
206 */
207 public static $plugin_dir;
208
209 /**
210 * Plugin url. set in constructor
211 *
212 * @var $plugin_url
213 */
214 public static $plugin_url;
215
216 /**
217 * Plugin name. set in constructor
218 *
219 * @var $plugin_name
220 */
221 public static $plugin_name;
222
223 /**
224 * Check if wp_mail is declared
225 *
226 * @var $wp_mail_conflict
227 */
228 static $wp_mail_conflict;
229
230 /**
231 * Class constructor
232 * Sets plugin url and directory and adds hooks to <i>init</i>. <i>admin_menu</i>
233 */
234 function __construct() {
235 // get basic info.
236 self::$plugin_dir = plugin_dir_path( __FILE__ );
237 self::$plugin_url = plugins_url( '', __FILE__ );
238 self::$plugin_name = plugin_basename( __FILE__ );
239
240 self::$wp_mail_conflict = false;
241
242 // api key for sendinblue.
243 $general_settings = get_option( self::MAIN_OPTION_NAME, array() );
244 self::$access_key = isset( $general_settings['access_key'] ) ? $general_settings['access_key'] : '';
245
246 self::$instance = $this;
247 add_action('plugins_loaded', array( &$this, 'brevo_wp_load' ) );
248 add_action( 'upgrader_process_complete', array( &$this, 'my_upgrade_function' ), 10, 2);
249 add_action( 'admin_init', array( &$this, 'admin_init' ), 9999 );
250 add_action( 'admin_menu', array( &$this, 'admin_menu' ), 9999 );
251 add_action('rest_api_init', array($this, 'create_brevo_rest_endpoints'));
252
253 add_action( 'wp_print_scripts', array( &$this, 'frontend_register_scripts' ), 9999 );
254 add_action( 'wp_enqueue_scripts', array( &$this, 'wp_head_ac' ), 999 );
255
256 // create custom url for form preview.
257 add_filter( 'query_vars', array( &$this, 'sib_query_vars' ) );
258 add_action( 'parse_request', array( &$this, 'sib_parse_request' ) );
259
260 add_action( 'wp_ajax_sib_validate_process', array( 'SIB_Page_Home', 'ajax_validation_process' ) );
261 add_action( 'wp_ajax_sib_validate_ma', array( 'SIB_Page_Home', 'ajax_validate_ma' ) );
262 add_action( 'wp_ajax_sib_activate_email_change', array( 'SIB_Page_Home', 'ajax_activate_email_change' ) );
263 add_action( 'wp_ajax_sib_sender_change', array( 'SIB_Page_Home', 'ajax_sender_change' ) );
264 add_action( 'wp_ajax_sib_send_email', array( 'SIB_Page_Home', 'ajax_send_email' ) );
265 add_action( 'wp_ajax_sib_remove_cache', array( 'SIB_Page_Home', 'ajax_remove_cache' ) );
266 add_action( 'wp_ajax_sib_sync_users', array( 'SIB_Page_Home', 'ajax_sync_users' ) );
267
268 add_action( 'wp_ajax_sib_change_template', array( 'SIB_Page_Form', 'ajax_change_template' ) );
269 add_action( 'wp_ajax_sib_get_lists', array( 'SIB_Page_Form', 'ajax_get_lists' ) );
270 add_action( 'wp_ajax_sib_get_templates', array( 'SIB_Page_Form', 'ajax_get_templates' ) );
271 add_action( 'wp_ajax_sib_get_attributes', array( 'SIB_Page_Form', 'ajax_get_attributes' ) );
272 add_action( 'wp_ajax_sib_update_form_html', array( 'SIB_Page_Form', 'ajax_update_html' ) );
273 add_action( 'wp_ajax_sib_copy_origin_form', array( 'SIB_Page_Form', 'ajax_copy_origin_form' ) );
274
275 add_action( 'wp_ajax_sib_get_country_prefix', array( $this, 'ajax_get_country_prefix' ) );
276 add_action( 'wp_ajax_nopriv_sib_get_country_prefix', array( $this, 'ajax_get_country_prefix' ) );
277
278 add_action( 'init', array( &$this, 'init' ) );
279
280 add_action( 'wp_login', array( &$this, 'sib_wp_login_identify' ), 10, 2 );
281
282 // change sib tables name on prior(2.6.9) versions.
283 SIB_Model_Users::add_prefix();
284 SIB_Forms::add_prefix();
285 SIB_Forms::modify_datatype();
286
287 if ( self::is_api_key_set() ) {
288 add_shortcode( 'sibwp_form', array( &$this, 'sibwp_form_shortcode' ) );
289 // register widget.
290 add_action( 'widgets_init', array( &$this, 'sib_create_widget' ) );
291
292 // create forms tables and create default form.
293 SIB_Forms::createTable();
294 // create users table.
295 SIB_Model_Users::createTable();
296 // add columns for old versions
297 SIB_Forms::alterTable();
298 SIB_Model_Users::add_user_added_date_column();
299 SIB_Model_Users::add_flag_doi_sent();
300 }
301
302 $use_api_version = get_option( 'sib_use_apiv2', '0' );
303 if ( '0' === $use_api_version ) {
304 self::uninstall();
305 update_option( 'sib_use_apiv2', '1' );
306 }
307
308 // Wpml plugin part.
309 if ( ! function_exists( 'is_plugin_active_for_network' ) ) :
310 require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
311 endif;
312 if ( in_array( 'sitepress-multilingual-cms/sitepress.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) || is_plugin_active_for_network( 'sitepress-multilingual-cms/sitepress.php' ) ) {
313 SIB_Forms_Lang::createTable();
314 add_action( 'sib_language_sidebar', array( $this, 'sib_create_language_sidebar' ) );
315 }
316
317 /**
318 * Hook wp_mail to send transactional emails
319 */
320
321 // check if wp_mail function is already declared by others.
322 if ( function_exists( 'wp_mail' ) ) {
323 self::$wp_mail_conflict = true;
324 }
325 $home_settings = get_option( SIB_Manager::HOME_OPTION_NAME, array() );
326
327 if( 'yes' === $home_settings['activate_email'] )
328 {
329 if ( false === self::$wp_mail_conflict ) {
330 /**
331 * Declare wp_mail function for Sendinblue SMTP module
332 *
333 * @param string $to - receiption email.
334 * @param string $subject - subject of email.
335 * @param string $message - message content.
336 * @param string $headers - header of email.
337 * @param array $attachments - attachments.
338 * @return bool
339 */
340 function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
341 $message = str_replace( 'NF_SIB', '', $message );
342 $message = str_replace( 'WC_SIB', '', $message );
343 try {
344 $sent = SIB_Manager::sib_email( $to, $subject, $message, $headers, $attachments );
345 if ( is_wp_error( $sent ) || ! isset( $sent['code'] ) || 'success' !== $sent['code'] ) {
346 try{
347 return true;
348 }catch( Exception $e ){
349 return false;
350 }
351 }
352 return true;
353 } catch ( Exception $e ) {
354 return false;
355 }
356 }
357 } else {
358 add_action( 'admin_notices', array( &$this, 'wpMailNotices' ) );
359 return;
360 }
361 }
362 }
363
364 /**
365 * Add identify tag for login users
366 *
367 * @param string $user_login - user login name.
368 * @param array $user - user.
369 */
370 function sib_wp_login_identify( $user_login, $user ) {
371
372 $userEmail = $user->user_email;
373 $data = array(
374 'email_id' => $userEmail,
375 'name' => $user_login,
376 );
377 SIB_API_Manager::identify_user( $data );
378 }
379
380 /**
381 * Initialize method. called on <i>init</i> action
382 */
383 function init() {
384 // Sign up process.
385 if ( isset( $_POST['sib_form_action'] ) && ( 'subscribe_form_submit' == sanitize_text_field($_POST['sib_form_action']) ) ) {
386 $this->signup_process();
387 }
388 // Subscribe.
389 if ( isset( $_GET['sib_action'] ) && ( 'subscribe' == sanitize_text_field($_GET['sib_action']) ) ) {
390 $code = isset( $_GET['code'] ) ? sanitize_text_field( $_GET['code'] ) : '';
391 $contact_info = SIB_Model_Users::get_data_by_code( $code );
392 $user_added_date = $contact_info['user_added_date'];
393 $current_date = gmdate( 'Y-m-d H:i:s' );
394 $date_diff = strtotime( $current_date ) - strtotime( $user_added_date );
395 if ( $date_diff > 5 ) {
396 SIB_API_Manager::subscribe( $contact_info );
397 } else {
398 $type = 'Bot Event';
399 SIB_API_Manager::template_subscribe( $type );
400 }
401 exit;
402 }
403 // Dismiss language notice.
404 if ( isset( $_GET['dismiss_admin_lang_notice'] ) && '1' == sanitize_text_field($_GET['dismiss_admin_lang_notice']) ) {
405 update_option( SIB_Manager::LANGUAGE_OPTION_NAME, true );
406 wp_safe_redirect( $_SERVER['HTTP_REFERER'] );
407 exit();
408 }
409
410 add_action( 'wp_head', array( &$this, 'install_ma_script' ) );
411 }
412
413 /**
414 * Hook admin_init
415 */
416 function admin_init() {
417 add_action( 'admin_action_sib_setting_subscription', array( 'SIB_Page_Form', 'save_setting_subscription' ) );
418 add_action( 'admin_action_nopriv_sib_setting_subscription', array( 'SIB_Page_Form', 'save_setting_subscription' ) );
419 SIB_Manager::LoadTextDomain();
420 $this->register_scripts();
421 $this->register_styles();
422 }
423
424 /**
425 * Hook admin_menu
426 */
427 function admin_menu() {
428 SIB_Manager::LoadTextDomain();
429 new SIB_Page_Home();
430 new SIB_Page_Form();
431 new SIB_Page_Statistics();
432
433 }
434
435 /**
436 * Register script for admin page
437 */
438 function register_scripts() {
439 wp_register_script( 'sib-bootstrap-js', self::$plugin_url . '/js/bootstrap/js/bootstrap.bundle.min.js', array( 'jquery' ), false );
440 wp_register_script( 'sib-admin-js', self::$plugin_url . '/js/admin.js', array( 'jquery' ), filemtime( self::$plugin_dir . '/js/admin.js' ) );
441 wp_register_script( 'sib-chosen-js', self::$plugin_url . '/js/chosen.jquery.min.js', array( 'jquery' ), false );
442 wp_enqueue_script('jquery-ui-datepicker');
443 wp_enqueue_script('jquery-ui-spinner');
444 }
445
446 /**
447 * Register stylesheet for admin page
448 */
449 function register_styles() {
450 wp_register_style( 'sib-bootstrap-css', self::$plugin_url . '/js/bootstrap/css/bootstrap.css', array(), false, 'all' );
451 wp_register_style( 'sib-fontawesome-css', self::$plugin_url . '/css/fontawesome/css/font-awesome.css', array(), false, 'all' );
452 wp_register_style( 'sib-chosen-css', self::$plugin_url . '/css/chosen.min.css' );
453 wp_register_style( 'sib-admin-css', self::$plugin_url . '/css/admin.css', array(), filemtime( self::$plugin_dir . '/css/admin.css' ), 'all' );
454 }
455
456 /**
457 * Registers scripts for frontend
458 */
459 function frontend_register_scripts() {
460
461 }
462
463 /**
464 * Enqueue script on front page
465 */
466 function wp_head_ac() {
467 wp_enqueue_script( 'sib-front-js', self::$plugin_url . '/js/mailin-front.js', array( 'jquery' ), filemtime( self::$plugin_dir . '/js/mailin-front.js' ), false );
468 wp_enqueue_style( 'sib-front-css', self::$plugin_url.'/css/mailin-front.css', array(), array(), 'all');
469 wp_localize_script(
470 'sib-front-js', 'sibErrMsg', array(
471 'invalidMail' => __( 'Please fill out valid email address', 'mailin' ),
472 'requiredField' => __( 'Please fill out required fields', 'mailin' ),
473 'invalidDateFormat' => __( 'Please fill out valid date format', 'mailin' ),
474 'invalidSMSFormat' => __( 'Please fill out valid phone number', 'mailin' ),
475 )
476 );
477 wp_localize_script(
478 'sib-front-js', 'ajax_sib_front_object',
479 array(
480 'ajax_url' => admin_url( 'admin-ajax.php' ),
481 'ajax_nonce' => wp_create_nonce( 'sib_front_ajax_nonce' ),
482 'flag_url' => plugins_url('img/flags/', __FILE__ ),
483 )
484 );
485 }
486
487 /**
488 * Install method is called once install this plugin.
489 * create tables, default option ...
490 */
491 static function install() {
492 $general_settings = get_option( self::MAIN_OPTION_NAME, array() );
493 $access_key = isset( $general_settings['access_key'] ) ? $general_settings['access_key'] : '';
494 if ( '' === $access_key ) {
495 // Default option when activate.
496 $home_settings = array(
497 'activate_email' => 'no',
498 'activate_ma' => 'default',
499 );
500 update_option( self::HOME_OPTION_NAME, $home_settings );
501 }
502
503 self::activate_brevo_connection();
504 }
505
506 /**
507 * Uninstall method is called once uninstall this plugin
508 * delete tables, options that used in plugin
509 */
510 static function uninstall() {
511 $setting = array();
512 update_option( SIB_Manager::MAIN_OPTION_NAME, $setting );
513
514 $home_settings = array(
515 'activate_email' => 'no',
516 'activate_ma' => 'default',
517 );
518 update_option( SIB_Manager::HOME_OPTION_NAME, $home_settings );
519
520 // Delete access_token.
521 $token_settings = array();
522 update_option( SIB_Manager::ACCESS_TOKEN_OPTION_NAME, $token_settings );
523
524 //Deactivate the connection on Brevo
525 self::deactivate_brevo_connection();
526
527 //Then delete the api key in our plugin
528 delete_option(SIB_Manager::API_KEY_V3_OPTION_NAME);
529 // Empty tables.
530 SIB_Model_Users::removeTable();
531 SIB_Forms::removeTable();
532 SIB_Forms_Lang::removeTable();
533
534 // Remove all transient.
535 SIB_API_Manager::remove_transients();
536 }
537
538 static function deactivate_brevo_connection()
539 {
540 $installationId = get_option( SIB_Manager::INSTALLATION_ID );
541 if(!empty($installationId))
542 {
543 $apiClient = new SendinblueApiClient();
544 $params["connection"] = 27;
545 $params["plugin_version"] = SendinblueApiClient::PLUGIN_VERSION;
546 $params["active"] = false;
547 $params["deactivated_at"] = gmdate("Y-m-d\TH:i:s\Z");
548 $apiClient->updateInstallationInfo($installationId, $params);
549 }
550 }
551
552 static function activate_brevo_connection()
553 {
554 $installationId = get_option( SIB_Manager::INSTALLATION_ID );
555 if(!empty($installationId))
556 {
557 $apiClient = new SendinblueApiClient();
558 $params["connection"] = 27;
559 $params["plugin_version"] = SendinblueApiClient::PLUGIN_VERSION;
560 $params["active"] = true;
561 $params["activated_at"] = gmdate("Y-m-d\TH:i:s\Z");
562 $apiClient->updateInstallationInfo($installationId, $params);
563 }
564 }
565
566 /**
567 * Deactivate method is called once deactivate this plugin
568 */
569 static function deactivate() {
570 update_option( SIB_Manager::LANGUAGE_OPTION_NAME, false );
571 // Remove service worker file.
572 self::uninstall_service_worker_script();
573 // Remove sync users option.
574 delete_option( 'sib_sync_users' );
575 // Remove all transient.
576 SIB_API_Manager::remove_transients();
577
578 //Also deactivate the connection on Brevo
579 self::deactivate_brevo_connection();
580 }
581
582 /**
583 * Check if plugin is logged in.
584 *
585 * @param bool $redirect
586 * @return bool
587 */
588 static function is_done_validation($redirect = true) {
589 if (self::is_api_key_set()) {
590 $apiClient = new SendinblueApiClient();
591 $apiClient->getAccount();
592 if ( SendinblueApiClient::RESPONSE_CODE_OK === $apiClient->getLastResponseCode() ) {
593 //This is only for those users who have an active connection but no installation id could be
594 //saved on their shop
595 $installationId = get_option( SIB_Manager::INSTALLATION_ID );
596 if(empty($installationId))
597 {
598 self::fetch_and_save_installation_id();
599 }
600 return true;
601 } elseif (SendinblueApiClient::RESPONSE_CODE_UNAUTHORIZED === $apiClient->getLastResponseCode()) {
602 delete_option(SIB_Manager::API_KEY_V3_OPTION_NAME);
603 }
604 }
605
606 if ($redirect) {
607 self::redirect_to_sib_plugin_homepage();
608 }
609
610 return false;
611 }
612
613 static function redirect_to_sib_plugin_homepage() {
614 wp_safe_redirect(add_query_arg('page', SIB_Page_Home::PAGE_ID, admin_url('admin.php')));
615 }
616
617 /**
618 * @return bool
619 */
620 static function is_api_key_set() {
621 $api_key = get_option(SIB_Manager::API_KEY_V3_OPTION_NAME);
622 return !empty($api_key);
623 }
624
625 static function is_ma_active() {
626 $general_settings = get_option( SIB_Manager::MAIN_OPTION_NAME, array() );
627 $ma_key = isset( $general_settings['ma_key'] ) ? sanitize_text_field($general_settings['ma_key']) : null;
628 if ( $ma_key === null || strlen($ma_key) === 0 ) {
629 return false;
630 }
631 $home_settings = get_option( SIB_Manager::HOME_OPTION_NAME, array() );
632 $activate_ma = isset( $home_settings['activate_ma'] ) ? $home_settings['activate_ma'] : 'default';
633 return 'no' !== $activate_ma;
634 }
635
636 static function fetch_and_save_installation_id()
637 {
638 $apiClient = new SendinblueApiClient();
639
640 $params["partnerName"] = "WORDPRESS";
641 $params["plugin_version"] = SendinblueApiClient::PLUGIN_VERSION;
642 $params["shop_url"] = get_home_url();
643 $params["active"] = true;
644 $params["connection"] = 27;
645 $response = $apiClient->createInstallationInfo($params);
646 if ( $apiClient->getLastResponseCode() === SendinblueApiClient::RESPONSE_CODE_CREATED )
647 {
648 if(!empty($response["id"]))
649 {
650 update_option(SIB_Manager::INSTALLATION_ID, $response["id"]);
651 }
652 }
653 }
654
655 /**
656 * Install service-worker script in plugin for push notifications
657 * @return void
658 */
659 static function install_service_worker_script($service_worker)
660 {
661 try {
662 $site_url = get_site_url();
663 $service_worker_file = str_contains($site_url, self::URL_CHECK_STAGING)
664 ? self::PUSHOWL_STAGING_URL
665 : self::PUSHOWL_PRODUCTION_URL;
666 $js_content = "importScripts('" . $service_worker_file . "');";
667 $service_worker_script = fopen($service_worker, "wb");
668 fwrite($service_worker_script, $js_content);
669 fclose($service_worker_script);
670 } catch (\Throwable $th) {
671 update_option('sib_service_worker_install_exception', $th->getMessage());
672 }
673 }
674
675 /**
676 * Uninstall service-worker script from plugin
677 * @return void
678 */
679 static function uninstall_service_worker_script()
680 {
681 try {
682 $service_worker_file = __DIR__ . self::SERVICE_WORKER_FILE_URL;
683 if (file_exists($service_worker_file)) {
684 wp_delete_file($service_worker_file);
685 }
686 update_option('sib_service_worker_install_exception', '');
687 } catch (\Throwable $th) {
688 update_option('sib_service_worker_uninstall_exception', $th->getMessage());
689 }
690 }
691
692 /**
693 * Install marketing automation script in header
694 */
695 function install_ma_script() {
696 if ( SIB_Manager::is_ma_active() ) {
697 $general_settings = get_option( SIB_Manager::MAIN_OPTION_NAME, array() );
698 $ma_key = isset( $general_settings['ma_key'] ) ? sanitize_text_field($general_settings['ma_key']) : null;
699 $service_worker = __DIR__ . self::SERVICE_WORKER_FILE_URL;
700 if ( ! file_exists($service_worker)) {
701 self::install_service_worker_script($service_worker);
702 }
703 $ma_email = '';
704 $current_user = wp_get_current_user();
705 if ( $current_user instanceof WP_User ) {
706 $ma_email = $current_user->user_email;
707 }
708 $pushOptions = json_encode(array(
709 'customDomain' => SIB_Manager::$plugin_url . '/',
710 'userId' => $ma_email ?: null,
711 ));
712 $output = '<script src="https://cdn.brevo.com/js/sdk-loader.js" async></script>';
713 $output .= '<script>window.Brevo = window.Brevo || [];
714 Brevo.push([
715 "init",
716 {
717 client_key:"' . $ma_key .'",
718 push: '.$pushOptions.',
719 ';
720 $output .= 'email_id : "' . sanitize_email($ma_email) . '",},]);</script>';
721 echo html_entity_decode($output);
722 } else {
723 self::uninstall_service_worker_script();
724 }
725
726 }
727
728 /**
729 * Register widget
730 */
731 function sib_create_widget() {
732 register_widget( 'SIB_Widget_Subscribe' );
733 }
734
735 /**
736 * Display form on front page
737 *
738 * @param string $frmID - form ID.
739 * @param string $lang - form language.
740 */
741 function generate_form_box( $frmID = '-1', $lang = '' ) {
742 if ( 'oldForm' == $frmID ) {
743 $frmID = get_option( 'sib_old_form_id' );
744 } elseif ( '' != $lang ) {
745 $trans_id = SIB_Forms_Lang::get_form_ID( $frmID, $lang );
746 if ( null != $trans_id ) {
747 $frmID = $trans_id;
748 }
749 }
750
751 $formData = SIB_Forms::getForm( $frmID );
752
753 if ( empty( $formData ) ) {
754 return;
755 }
756 // Add Google recaptcha
757 if( '0' != $formData['gCaptcha'] && $formData['selectCaptchaType'] != 3) {
758 if( '1' == $formData['gCaptcha'] ) { // For old forms.
759 $formData['html'] = preg_replace( '/([\s\S]*?)<div class="g-recaptcha"[\s\S]*?data-size="invisible"><\/div>/', '$1', $formData['html'] );
760 }
761 if ( '3' == $formData['gCaptcha'] ) // The case of using google recaptcha.
762 {
763 ?>
764 <script type="text/javascript">
765 var onloadSibCallback = function () {
766 jQuery('.g-recaptcha').each(function (index, el) {
767 grecaptcha.render(el, {
768 'sitekey': jQuery(el).attr('data-sitekey')
769 });
770 });
771 };
772 </script>
773 <?php
774 } else { // The case of using google invisible recaptcha.
775 $formData['html'] = str_contains( $formData['html'], 'sib-default-btn' ) ? str_replace(
776 'type="submit"',
777 'type="submit" id="invisible"',
778 $formData['html']
779 ) : $formData['html'];
780 ?>
781 <script type="text/javascript">
782 var gCaptchaSibWidget;
783 var onloadSibCallbackInvisible = function () {
784
785 var element = document.getElementsByClassName('sib-default-btn');
786 var countInvisible = 0;
787 var indexArray = [];
788 jQuery('.sib-default-btn').each(function (index, el) {
789 if ((jQuery(el).attr('id') == "invisible")) {
790 indexArray[countInvisible] = index;
791 countInvisible++
792 }
793 });
794
795 jQuery('.invi-recaptcha').each(function (index, el) {
796 grecaptcha.render(element[indexArray[index]], {
797 'sitekey': jQuery(el).attr('data-sitekey'),
798 'callback': sibVerifyCallback,
799 });
800 });
801 };
802 </script>
803 <?php
804 }
805 ?>
806 <script src="https://www.google.com/recaptcha/api.js?onload=<?php
807 echo esc_attr(
808 $formData['gCaptcha'] == '2' ? 'onloadSibCallbackInvisible' : 'onloadSibCallback'
809 ) ?>&render=explicit" async defer></script>
810 <?php
811 } else if ('0' != $formData['gCaptcha'] && $formData['selectCaptchaType'] == 3) { ?>
812
813 <script src="https://challenges.cloudflare.com/turnstile/v0/api.js"></script>
814
815 <?php } ?>
816
817 <form id="sib_signup_form_<?php echo esc_attr( $frmID ); ?>" method="post" class="sib_signup_form">
818 <div class="sib_loader" style="display:none;"><img
819 src="<?php echo esc_url( includes_url() ); ?>images/spinner.gif" alt="loader"></div>
820 <input type="hidden" name="sib_form_action" value="subscribe_form_submit">
821 <input type="hidden" name="sib_form_id" value="<?php echo esc_attr( $frmID ); ?>">
822 <input type="hidden" name="sib_form_alert_notice" value="<?php echo esc_attr($formData['requiredMsg']); ?>">
823 <input type="hidden" name="sib_form_invalid_email_notice" value="<?php echo esc_attr($formData['invalidMsg']); ?>">
824 <input type="hidden" name="sib_security" value="<?php echo esc_attr( wp_create_nonce( 'sib_front_ajax_nonce' ) ); ?>">
825 <div class="sib_signup_box_inside_<?php echo esc_attr( $frmID ); ?>">
826 <div style="/*display:none*/" class="sib_msg_disp">
827 </div>
828 <?php
829 if (($formData['gCaptcha'] == '2') && false === strpos(
830 $formData['html'],
831 'id="sib_captcha_invisible"'
832 )) { ?>
833 <div id="sib_captcha_invisible" class="invi-recaptcha" data-sitekey="<?php
834 echo esc_attr($formData['gCaptcha_site']); ?>"></div>
835 <?php
836 } ?>
837 <?php
838 // phpcs:ignore
839
840 if (false === strpos($formData['html'], 'class="g-recaptcha"')) {
841 $formData['html'] = str_replace(
842 'id="sib_captcha"',
843 'id="sib_captcha" class="g-recaptcha" data-sitekey="' . $formData['gCaptcha_site'] . '"',
844 $formData['html']
845 );
846 }
847
848 echo wp_kses($formData['html'], SIB_Manager::wordpress_allowed_attributes());
849 ?>
850 </div>
851 </form>
852 <style>
853 <?php
854
855 if ( ! $formData['dependTheme'] ) {
856 // Custom css.
857 $formData['css'] = str_replace( '[form]', 'form#sib_signup_form_' . $frmID, $formData['css'] );
858 echo esc_html($formData['css']);
859 }
860 $msgCss = str_replace( '[form]', 'form#sib_signup_form_' . $frmID, SIB_Forms::getDefaultMessageCss() );
861 echo esc_html($msgCss);
862 ?>
863 </style>
864 <?php
865 }
866
867 /**
868 * Shortcode for sign up form
869 *
870 * @param array $atts - shortcode parameter.
871 * @return string
872 */
873 function sibwp_form_shortcode( $atts ) {
874 $pull_atts = shortcode_atts(
875 array(
876 'id' => 'oldForm', // We will return 'oldForm' for shortcode of old form.
877 ), $atts
878 );
879 $frmID = $pull_atts['id'];
880 $lang = defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : '';
881
882 ob_start();
883 $this->generate_form_box( $frmID, $lang );
884
885 $output_string = ob_get_contents();
886 ob_end_clean();
887 return $output_string;
888 }
889
890 /**
891 * Sign up process
892 */
893 function signup_process() {
894 //Handling of backslash added by WP because magic quotes are enabled by default
895 array_walk_recursive( $_POST, function(&$value) {
896 $value = stripslashes($value);
897 });
898
899 if ( empty( $_POST['sib_security'] ) || empty(wp_verify_nonce($_POST['sib_security'], 'sib_front_ajax_nonce'))) {
900 wp_send_json(
901 array(
902 'status' => 'sib_security',
903 'msg' => 'Invalid Token Provided.',
904 )
905 );
906 }
907 $formID = isset( $_POST['sib_form_id'] ) ? sanitize_text_field( $_POST['sib_form_id'] ) : 1;
908 if ( 'oldForm' == $formID ) {
909 $formID = get_option( 'sib_old_form_id' );
910 }
911 $formData = SIB_Forms::getForm( $formID );
912
913 if (!SIB_Manager::is_done_validation(false) || 0 == count($formData)) {
914 wp_send_json(
915 array(
916 'status' => 'failure',
917 'msg' => array("errorMsg" => "Something wrong occurred"),
918 )
919 );
920 }
921 $turnstileCaptcha = false;
922 if ( '0' != $formData['gCaptcha'] && 3 != $formData['selectCaptchaType']) {
923 $turnstileCaptcha = true;
924 if ( ! isset( $_POST['g-recaptcha-response'] ) || empty( $_POST['g-recaptcha-response'] ) ) {
925 wp_send_json(
926 array(
927 'status' => 'gcaptchaEmpty',
928 'msg' => 'Please click on the reCAPTCHA box.',
929 )
930 );
931 }
932 $secret = $formData['gCaptcha_secret'];
933
934 $data = array(
935 'secret' => $secret,
936 'response' => sanitize_text_field( $_POST['g-recaptcha-response'] ),
937 );
938
939 $args = [
940 'method' => 'POST',
941 ];
942
943 try {
944 $data = wp_remote_retrieve_body(wp_remote_request(sprintf(self::RECAPTCHA_API_TEMPLATE, http_build_query($data)), $args));
945 $responseData = json_decode($data);
946 if ( ! $responseData->success ) {
947 wp_send_json(
948 array(
949 'status' => 'gcaptchaFail',
950 'msg' => 'Robot verification failed, please try again.',
951 )
952 );
953 }
954 } catch (Exception $exception) {
955 wp_send_json(
956 array(
957 'status' => 'gcaptchaFail',
958 'msg' => $exception->getMessage(),
959 )
960 );
961 }
962 } else if ( '0' != $formData['gCaptcha'] && 3 == $formData['selectCaptchaType'] ) {
963 $turnstileCaptcha = true;
964 if ( ! isset( $_POST['cf-turnstile-response'] ) || empty( $_POST['cf-turnstile-response'] ) ) {
965 wp_send_json(
966 array(
967 'status' => 'gcaptchaEmpty',
968 'msg' => 'Captcha couldnot be verified. Please refresh the page.',
969 )
970 );
971 }
972 $secret = $formData['cCaptcha_secret'];
973
974 $args = [
975 'method' => 'POST',
976 ];
977
978 try {
979
980 $headers = array(
981 'body' => [
982 'secret' => $secret,
983 'response' => sanitize_text_field( $_POST['cf-turnstile-response'] )
984 ]
985 );
986 $verify = wp_remote_post(self::TURNSTILE_SITE_VERIFY, $headers);
987 $verify = wp_remote_retrieve_body($verify);
988 $response = json_decode($verify);
989
990 if($response->success) {
991 $results['success'] = $response->success;
992 } else {
993 $results['success'] = false;
994 }
995
996 if ( ! $response->success ) {
997 wp_send_json(
998 array(
999 'status' => 'gcaptchaFail',
1000 'msg' => 'Robot verification failed, please try again.',
1001 )
1002 );
1003 }
1004 } catch (Exception $exception) {
1005 wp_send_json(
1006 array(
1007 'status' => 'gcaptchaFail',
1008 'msg' => $exception->getMessage(),
1009 )
1010 );
1011 }
1012 }
1013
1014 $listID = $formData['listID'];
1015 if (empty($listID)) {
1016 $listID = array();
1017 }
1018 $interestingLists = isset( $_POST['interestingLists']) ? array_map( 'sanitize_text_field', $_POST['interestingLists'] ) : array();
1019 $expectedLists = isset( $_POST['listIDs'] ) ? array_map( 'sanitize_text_field', $_POST['listIDs'] ) : array();
1020 if ( empty($interestingLists) )
1021 {
1022 $unlinkedLists = [];
1023 }
1024 else{
1025 $unwantedLists = array_diff( $interestingLists, $expectedLists );
1026 $unlinkedLists = array_diff( $unwantedLists, $listID);
1027 $listID = array_unique(array_merge( $listID, $expectedLists ));
1028 }
1029
1030 $email = isset( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : '';
1031 if ( ! is_email( $email ) ) {
1032 return;
1033 }
1034
1035 $isDoubleOptin = $formData['isDopt'];
1036 $isOptin = $formData['isOpt'];
1037 $redirectUrlInEmail = $formData['redirectInEmail'];
1038 $redirectUrlInForm = $formData['redirectInForm'];
1039
1040 $info = array();
1041 $attributes = explode( ',', $formData['attributes'] ); // String to array.
1042 if ( isset( $attributes ) && is_array( $attributes ) ) {
1043 foreach ( $_POST as $postAttribute => $postAttributeValue ) {
1044 $correspondingSibAttribute = $this->getCorrespondingSibAttribute($postAttribute, $attributes);
1045 if (!empty($correspondingSibAttribute)) {
1046 $info[ $correspondingSibAttribute ] = sanitize_text_field( $postAttributeValue );
1047 }
1048 }
1049 }
1050 $templateID = $formData['templateID'];
1051
1052 if ( $isDoubleOptin ) {
1053 /*
1054 * Double optin process
1055 * 1. add record to db
1056 * 2. send confirmation email with activate code
1057 */
1058 $result = "success";
1059 // Send a double optin confirm email.
1060 if ( 'success' == $result ) {
1061 // Add a recode with activate code in db.
1062 $activateCode = $this->create_activate_code( $email, $info, $formID, $listID, $redirectUrlInEmail, $unlinkedLists );
1063 SIB_API_Manager::send_comfirm_email( $email, 'double-optin', $templateID, $info, $activateCode );
1064 }
1065 } elseif ( $isOptin ) {
1066 $result = SIB_API_Manager::create_subscriber( $email, $listID, $info, 'confirm', $unlinkedLists );
1067 if ( 'success' == $result ) {
1068 // Send a confirm email.
1069 SIB_API_Manager::send_comfirm_email( $email, 'confirm', $templateID, $info );
1070 }
1071 } else {
1072 $result = SIB_API_Manager::create_subscriber( $email, $listID, $info, 'simple', $unlinkedLists );
1073 }
1074 $msg = array(
1075 'successMsg' => $formData['successMsg'],
1076 'errorMsg' => $formData['errorMsg'],
1077 'existMsg' => $formData['existMsg'],
1078 'invalidMsg' => $formData['invalidMsg'],
1079 );
1080
1081 wp_send_json(
1082 array(
1083 'status' => $result,
1084 'msg' => $msg,
1085 'redirect' => $redirectUrlInForm,
1086 'turnstileCaptcha' => $turnstileCaptcha,
1087 )
1088 );
1089 }
1090
1091 /**
1092 * Create activate code for Double optin
1093 *
1094 * @param string $email - user email.
1095 * @param array $info - info.
1096 * @param string $formID - form ID.
1097 * @param array $listIDs - lists.
1098 * @param string $redirectUrl - redirect url.
1099 * @return string - activate code.
1100 */
1101 function create_activate_code( $email, $info, $formID, $listIDs, $redirectUrl, $unlinkedLists = null ) {
1102 $data = SIB_Model_Users::get_data_by_email( $email, $formID );
1103 $date = gmdate( 'Y-m-d H:i:s' );
1104 if ( $unlinkedLists != null )
1105 {
1106 $info['unlinkedLists'] = $unlinkedLists;
1107 }
1108 if ( false == $data ) {
1109 $uniqid = uniqid();
1110 $data = array(
1111 'email' => $email,
1112 'code' => $uniqid,
1113 'info' => maybe_serialize( $info ),
1114 'frmid' => $formID,
1115 'listIDs' => maybe_serialize( $listIDs ),
1116 'redirectUrl' => $redirectUrl,
1117 'user_added_date' => $date,
1118 'doi_sent' => 0,
1119 );
1120 SIB_Model_Users::add_record( $data );
1121 } else {
1122 $update_data = array(
1123 'id' => $data['id'],
1124 'email' => $email,
1125 'info' => maybe_serialize( $info ),
1126 );
1127 SIB_Model_Users::update_element( $update_data );
1128 $uniqid = $data['code'];
1129 }
1130 return $uniqid;
1131 }
1132
1133 /**
1134 * Use Sendinblue SMTP to send all emails
1135 *
1136 * @param string $to - reception email.
1137 * @param string $subject - subject of email.
1138 * @param string $message - message of email.
1139 * @param string $headers - header of email.
1140 * @param array $attachments - attachments.
1141 */
1142 static function wp_mail_native( $to, $subject, $message, $headers = '', $attachments = array() ) {
1143 $result = require self::$plugin_dir . '/inc/function.wp_mail.php';
1144 return $result;
1145 }
1146
1147 /**
1148 * To send the transactional email via Sendinblue
1149 * hook wp_mail
1150 *
1151 * @param string $to - reception email.
1152 * @param string $subject - subject of email.
1153 * @param string $message - message of email.
1154 * @param string $headers - header of email.
1155 * @param array $attachments - attachments
1156 * @param array $tags - tag.
1157 * @param string $from_name - sender name.
1158 * @param string $from_email - sender email.
1159 * @return mixed|WP_Error
1160 */
1161 static function sib_email( $to, $subject, $message, $headers = '', $attachments = array(), $tags = array(), $from_name = '', $from_email = '' ) {
1162 $data = [];
1163 // Compact the input, apply the filters, and extract them back out.
1164 extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) );
1165
1166 if ( !empty( $attachments ) && ! is_array( $attachments ) ) {
1167 $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
1168 }
1169
1170 // From email and name.
1171 $home_settings = get_option( SIB_Manager::HOME_OPTION_NAME );
1172 if ( isset( $home_settings['sender'] ) ) {
1173 $from_name = $home_settings['from_name'];
1174 $from_email = $home_settings['from_email'];
1175 } else {
1176 $from_email = trim( get_bloginfo( 'admin_email' ) );
1177 $from_name = trim( get_bloginfo( 'name' ) );
1178 }
1179
1180 //Set additional address fields as empty
1181 $bcc = array();
1182 $cc = array();
1183 $reply_to = array();
1184 if ( ! is_array( $to ) ) {
1185 $to = explode( ',', $to );
1186 }
1187
1188 $from_email = apply_filters( 'wp_mail_from', $from_email );
1189 $from_name = apply_filters( 'wp_mail_from_name', $from_name );
1190
1191 if ( !empty( $headers ) ) {
1192 if( is_array( $headers ) ){
1193 foreach ($headers as $key => $val) {
1194 if( stripos($val, "Content-Type: text/html") !== false ) {
1195 unset( $headers[$key] );
1196 }
1197 }
1198 $headers = array_values( $headers );
1199 if( count( $headers ) == 1 && $headers[0] == '' ) {
1200 unset( $headers[0] );
1201 }
1202 }
1203 if( is_string( $headers ) ){
1204 $headers = str_replace("Content-Type: text/html", "", $headers);
1205 }
1206 if( !empty( $headers ) ){
1207 $data['headers'] = $headers;
1208 }
1209 if ( ! is_array( $headers ) ) {
1210 // Explode the headers out, so this function can take both.
1211 // string headers and an array of headers.
1212 $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
1213 } else {
1214 $tempheaders = $headers;
1215 }
1216 $headers = array();
1217 // If it's actually got contents.
1218 if ( ! empty( $tempheaders ) ) {
1219 // Iterate through the raw headers.
1220 foreach ( (array) $tempheaders as $header ) {
1221 if ( strpos( $header, ':' ) === false ) {
1222 if ( false !== stripos( $header, 'boundary=' ) ) {
1223 $parts = preg_split( '/boundary=/i', trim( $header ) );
1224 $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
1225 }
1226 continue;
1227 }
1228 // Explode them out.
1229 list($name, $content) = explode( ':', trim( $header ), 2 );
1230
1231 // Cleanup crew.
1232 $name = trim( $name );
1233 $content = trim( $content );
1234
1235 switch ( strtolower( $name ) ) {
1236 case 'content-type':
1237 $headers[ trim( $name ) ] = trim( $content );
1238 break;
1239 case 'x-mailin-tag':
1240 $headers[ trim( $name ) ] = trim( $content );
1241 break;
1242 case 'from':
1243 if ( strpos( $content, '<' ) !== false ) {
1244 // So... making my life hard again?
1245 $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 );
1246 $from_name = str_replace( '"', '', $from_name );
1247 $from_name = trim( $from_name );
1248
1249 $from_email = substr( $content, strpos( $content, '<' ) + 1 );
1250 $from_email = str_replace( '>', '', $from_email );
1251 $from_email = trim( $from_email );
1252 } else {
1253 $from_name = '';
1254 $from_email = trim( $content );
1255 }
1256 break;
1257
1258 case 'cc':
1259 $cc = array_merge( (array) $cc, explode( ',', $content ) );
1260 break;
1261
1262 case 'bcc':
1263 $bcc = array_merge( (array) $bcc, explode( ',', $content ) );
1264 break;
1265
1266 case 'reply-to':
1267 $reply_to = array_merge( (array) $reply_to, explode( ',', $content ) );
1268 break;
1269 default:
1270 break;
1271 }
1272 }
1273 }
1274 }
1275
1276 // Set destination addresses, using appropriate methods for handling addresses.
1277 $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
1278 $processed_address_fields = self::processAddressFields($address_headers);
1279 $data = array_merge($data, $processed_address_fields);
1280 // Attachments.
1281 $attachment_content = array();
1282 if ( ! empty( $attachments ) ) {
1283 foreach ( $attachments as $attachment ) {
1284 if ( !empty( $attachment ) ) {
1285 $content = self::getAttachmentStruct( $attachment );
1286 if ( ! is_wp_error( $content ) ) {
1287 array_push( $attachment_content, $content );
1288 }
1289 }
1290 }
1291 if ( !empty( $attachment_content ) ) {
1292 $data["attachment"] = $attachment_content;
1293 }
1294 }
1295
1296 // Common transformations for the HTML part.
1297 // If it is text/plain, New line break found.
1298 if ( strpos( $message, '</table>' ) === false && strpos( $message, '</div>' ) === false ) {
1299 if ( strpos( $message, "\n" ) !== false ) {
1300 if ( is_array( $message ) ) {
1301 foreach ( $message as &$value ) {
1302 $value['content'] = preg_replace( '#<(https?://[^*]+)>#', '$1', $value['content'] );
1303 $value['content'] = nl2br( $value['content'] );
1304 }
1305 } else {
1306 $message = preg_replace( '#<(https?://[^*]+)>#', '$1', $message );
1307 $message = nl2br( $message );
1308 }
1309 }
1310 }
1311 // Sending...
1312 $data['sender'] = ['email' => $from_email, 'name' => $from_name ];
1313 $data['subject'] = $subject;
1314 $data['htmlContent'] = $message;
1315
1316 try {
1317 $sent = SIB_API_Manager::send_email( $data );
1318 return $sent;
1319 } catch ( Exception $e ) {
1320 return new WP_Error( $e->getMessage() );
1321 }
1322 }
1323
1324 /**
1325 * @param array $address_fields
1326 * @return array
1327 */
1328 private static function processAddressFields($address_fields)
1329 {
1330 $data = [
1331 'to' => [],
1332 'cc' => [],
1333 'bcc' => [],
1334 'replyTo' => [],
1335 ];
1336
1337 $address_fields['reply_to'] = is_array($address_fields['reply_to'])
1338 && count($address_fields['reply_to']) > 1 ? $address_fields['reply_to'][0] : $address_fields['reply_to'];
1339 foreach ($address_fields as $address_header => $addresses) {
1340 if (empty($addresses)) {
1341 continue;
1342 }
1343
1344 foreach ((array) $addresses as $address) {
1345 // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>".
1346 if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
1347 if (count($matches) == 3) {
1348 $address = preg_replace('/\s+/', '', $matches[2]); //strip whitespaces
1349 }
1350 }
1351
1352 switch ($address_header) {
1353 case 'to':
1354 $data['to'][] = ['email' => $address];
1355 break;
1356 case 'cc':
1357 $data['cc'][] = ['email' => $address];
1358 break;
1359 case 'bcc':
1360 $data['bcc'][] = ['email' => $address];
1361 break;
1362 case 'reply_to':
1363 $data['replyTo']['email'] = $address;
1364 break;
1365 }
1366 }
1367 }
1368 return $data;
1369 }
1370
1371 /**
1372 * @param string $path - attachment file path
1373 * @return array|WP_Error
1374 */
1375 static function getAttachmentStruct( $path ) {
1376
1377 $struct = array();
1378
1379 try {
1380
1381 if ( ! @is_file( $path ) ) {
1382 throw new Exception( $path . ' is not a valid file.' );
1383 }
1384
1385 $filename = basename( $path );
1386
1387 if ( ! function_exists( 'get_magic_quotes' ) ) {
1388 /**
1389 * @return bool
1390 */
1391 function get_magic_quotes() {
1392 return false;
1393 }
1394 }
1395 if ( ! function_exists( 'set_magic_quotes' ) ) {
1396 /**
1397 * @param $value
1398 * @return bool
1399 */
1400 function set_magic_quotes( $value ) {
1401 return true;
1402 }
1403 }
1404
1405 $isMagicQuotesSupported = version_compare( PHP_VERSION, '5.3.0', '<' )
1406 && function_exists( 'get_magic_quotes_runtime' )
1407 && function_exists( 'set_magic_quotes_runtime' );
1408
1409 if ( $isMagicQuotesSupported ) {
1410 // Escape linters check.
1411 $getMagicQuotesRuntimeFunc = 'get_magic_quotes_runtime';
1412 $setMagicQuotesRuntimeFunc = 'set_magic_quotes_runtime';
1413
1414 // Save magic quotes value.
1415 $magicQuotes = $getMagicQuotesRuntimeFunc();
1416 $setMagicQuotesRuntimeFunc (0);
1417 }
1418
1419 $file_buffer = file_get_contents( $path );
1420 $file_buffer = base64_encode($file_buffer);
1421
1422 if ( $isMagicQuotesSupported ) {
1423 // Restore magic quotes value.
1424 $setMagicQuotesRuntimeFunc($magicQuotes);
1425 }
1426
1427 $struct["name"] = $filename;
1428 $struct["content"] = $file_buffer;
1429
1430 } catch ( Exception $e ) {
1431 return new WP_Error( 'Error creating the attachment structure: ' . $e->getMessage() );
1432 }
1433
1434 return $struct;
1435 }
1436
1437 /**
1438 * Create custom page for form preview
1439 *
1440 * @param array $query_vars - query.
1441 * @return array
1442 */
1443 function sib_query_vars( $query_vars ) {
1444 $query_vars[] = 'sib_form';
1445 return $query_vars;
1446 }
1447
1448 /**
1449 * Parse request
1450 *
1451 * @param mixed $wp - object.
1452 */
1453 function sib_parse_request( &$wp ) {
1454 if ( array_key_exists( 'sib_form', $wp->query_vars ) ) {
1455 include 'inc/sib-form-preview.php';
1456 exit();
1457 }
1458 }
1459
1460 /**
1461 * Load Text domain.
1462 */
1463 static function LoadTextDomain() {
1464 // Load lang file.
1465 $i18n_file_name = 'mailin';
1466 $locale = apply_filters( 'plugin_locale', get_locale(), $i18n_file_name );
1467 // $locale = 'fr_FR';
1468 $filename = plugin_dir_path( __FILE__ ) . '/lang/' . $i18n_file_name . '-' . $locale . '.mo';
1469 load_textdomain( 'mailin', $filename );
1470 }
1471
1472 /**
1473 * Notice the language is difference than site's language
1474 */
1475 static function language_admin_notice() {
1476 if ( ! get_option( SIB_Manager::LANGUAGE_OPTION_NAME ) ) {
1477 $lang_prefix = substr( get_bloginfo( 'language' ), 0, 2 );
1478 $lang = self::getLanguageName( $lang_prefix );
1479 $class = 'error';
1480 $message = sprintf( 'Please note that your Brevo account is in %s, but Brevo WordPress plugin is only available in English / French for now. Sorry for inconvenience.', $lang );
1481 if ( 'en' !== $lang_prefix && 'fr' !== $lang_prefix ) {
1482 // phpcs:ignore
1483 echo ( "<div class=\"$class\" style='margin-left: 2px;margin-bottom: 4px;'> <p>$message<a class='' href='?dismiss_admin_lang_notice=1'> No problem...</a></p></div>" );
1484 }
1485 }
1486 }
1487
1488 /**
1489 * Notice wp_mail is not possible
1490 */
1491 static function wpMailNotices() {
1492 if ( self::$wp_mail_conflict ) {
1493 echo ( '<div class="error"><p>' . __( 'You cannot use Brevo SMTP now because wp_mail has been declared by another process or plugin. ', 'mailin' ) . '</p></div>' );
1494 }
1495 }
1496
1497 /**
1498 * Names of languages.
1499 *
1500 * @param string $prefix - language.
1501 * @return mixed
1502 */
1503 public static function getLanguageName( $prefix = 'en' ) {
1504 $lang = array();
1505 $lang['de'] = 'Deutsch';
1506 $lang['en'] = 'English';
1507 $lang['zh'] = '中文';
1508 $lang['ru'] = 'Русский';
1509 $lang['fi'] = 'suomi';
1510 $lang['fr'] = 'Français';
1511 $lang['nl'] = 'Nederlands';
1512 $lang['sv'] = 'Svenska';
1513 $lang['it'] = 'Italiano';
1514 $lang['ro'] = 'Română';
1515 $lang['hu'] = 'Magyar';
1516 $lang['ja'] = '日本語';
1517 $lang['es'] = 'Español';
1518 $lang['vi'] = 'Tiếng Việt';
1519 $lang['ar'] = 'العربية';
1520 $lang['pt'] = 'Português';
1521 $lang['pb'] = 'Português do Brasil';
1522 $lang['pl'] = 'Polski';
1523 $lang['gl'] = 'galego';
1524 $lang['tr'] = 'Turkish';
1525 $lang['et'] = 'Eesti';
1526 $lang['hr'] = 'Hrvatski';
1527 $lang['eu'] = 'Euskera';
1528 $lang['el'] = 'Ελληνικά';
1529 $lang['ua'] = 'Українська';
1530 $lang['ko'] = '한국어';
1531
1532 return $lang[ $prefix ];
1533 }
1534
1535 /**
1536 * Create language sidebar for wpml plugin.
1537 */
1538 public function sib_create_language_sidebar() {
1539 $languages = apply_filters( 'wpml_active_languages', array() );
1540 $page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
1541 $action = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : '';
1542 $frmID = isset( $_GET['id'] ) ? sanitize_text_field( $_GET['id'] ) : '';
1543 $pID = isset( $_GET['pid'] ) ? sanitize_text_field( $_GET['pid'] ) : '';
1544 $parent = true;
1545 if ( '' !== $frmID && '' !== $pID ) {
1546 $lang = SIB_Forms_Lang::get_lang( $frmID, $pID );
1547 $parent = false;
1548 } else {
1549 $lang = ICL_LANGUAGE_CODE;
1550 if ( '' !== $frmID && '' === $pID ) {
1551 $pID = $frmID;
1552
1553 }
1554 }
1555
1556 if ( 'sib_page_form' === $page && 'edit' === $action ) {
1557 ?>
1558 <div class="panel panel-default text-left box-border-box sib-small-content">
1559 <div class="panel-heading"><strong><?php esc_attr_e( 'About Brevo', 'mailin' ); ?></strong></div>
1560 <div class="panel-body">
1561 <p>
1562 <label for='sib_form_language'><?php esc_attr_e( 'Language of this form:', 'mailin' ); ?> </label>
1563 <select id="sib_form_lang" name="sib_form_lang" data-selected="">
1564 <?php
1565 foreach ( $languages as $language ) {
1566 $selected = (isset($language['code']) && ($language['code'] == $lang)) ? 'selected' : '';
1567 if ( isset($language['code']) && $language['code'] == $lang && true === $parent ) {
1568 $option_text = '<option value="" ' . $selected . '>' . $language['native_name'] . '</option>';
1569 } else {
1570 $exist = SIB_Forms_Lang::get_form_ID( $pID, $language['language_code'] );
1571
1572 if ( null === $exist ) {
1573 continue;
1574 } else {
1575 $option_text = ( 'selected' === $selected ) ?
1576 sprintf( '<option value="" selected>%s</option>', esc_html( $language['native_name'] ) ) :
1577 sprintf( '<option value="%s" %s>%s</option>',
1578 esc_url( add_query_arg( array(
1579 'page' => sanitize_text_field( $_REQUEST['page'] ),
1580 'action' => 'edit',
1581 'pid' => absint( $pID ),
1582 'lang' => sanitize_text_field( $language['language_code'] )
1583 ) ) ),
1584 $selected,
1585 esc_html( $language['native_name'] )
1586 );
1587 }
1588 }
1589 echo $option_text ;
1590 }
1591 ?>
1592 </select>
1593 </p>
1594 <div class="sib_form_translate">
1595 <p>
1596 <label><?php esc_attr_e( 'Translate this form', 'mailin' ); ?></label>
1597 </p>
1598 <table aria-describedby="wpml-language-table" class="sib_form_trans_table" style="border: 1px solid #8cceea;">
1599 <tr>
1600 <?php
1601 foreach ( $languages as $language ) {
1602 if ( isset($language['code']) && $language['code'] == $lang ) {
1603 continue;
1604 }
1605 ?>
1606 <th style="text-align: center;"><img
1607 src="<?php echo esc_url( $language['country_flag_url'] ); ?>" alt="Flag of <?php echo esc_attr( $language['translated_name'] ); ?>"></th>
1608 <?php
1609 }
1610 ?>
1611 </tr>
1612 <tr style="background-color: #EFF8FC;">
1613 <?php
1614 foreach ( $languages as $language ) {
1615 if ( isset($language['code']) && $language['code'] == $lang ) {
1616 continue;
1617 }
1618 if ( '' === $pID ) {
1619 $img_src = plugins_url( 'img/add_translation_disabled.png', __FILE__ );
1620 $td = '<img src="' . $img_src . '" style="margin:2px;">';
1621 } else {
1622 $exist = SIB_Forms_Lang::get_form_ID( $pID, $language['language_code'] );
1623
1624 if ( null === $exist ) {
1625 $img_src = plugins_url( 'img/add_translation.png', __FILE__ );
1626
1627 $href = sprintf( '<a class="sib-form-redirect" href="?page=%s&action=%s&pid=%s&lang=%s" style="width: 20px; text-align: center;padding: 2px 1px;">', esc_attr( $_REQUEST['page'] ), 'edit', absint( $pID ), $language['language_code'] );
1628 $td = $href . '<img src="' . $img_src . '" style="margin:2px;"></a>';
1629 } else {
1630 $img_src = plugins_url( 'img/edit_translation.png', __FILE__ );
1631 $href = sprintf( '<a class="sib-form-redirect" href="%s" style="width: 20px; text-align: center;padding: 2px 1px;">', esc_url( add_query_arg( array(
1632 'page' => sanitize_text_field( $_REQUEST['page'] ),
1633 'action' => 'edit',
1634 'id' => absint( $exist ),
1635 'pid' => absint( $pID ),
1636 'lang' => sanitize_text_field( $language['language_code'] )
1637 ) ) ) );
1638 $td = $href . '<img src="' . $img_src . '" style="margin:2px;"></a>';
1639 }
1640 }
1641 ?>
1642 <td style="text-align: center;"><?php echo wp_kses($td, wp_kses_allowed_html('post')); ?></td>
1643 <?php
1644 }
1645 ?>
1646 </tr>
1647 </table>
1648 </div>
1649 <?php if ( isset( $_GET['pid'] ) ) { ?>
1650 <div class="sib-form-duplicate">
1651 <button class="btn btn-default sib-duplicate-btn"><?php esc_attr_e( 'Copy content from origin form', 'mailin' ); ?></button>
1652 <span class="sib-spin"><i
1653 class="fa fa-circle-o-notch fa-spin fa-lg"></i>&nbsp;&nbsp;</span>
1654 <i title="<?php echo esc_attr_e( 'Copy content from origin form', 'mailin' ); ?>"
1655 data-container="body" data-toggle="popover" data-placement="left"
1656 data-content="<?php echo esc_attr_e( 'You can copy contents from origin form. You need to translate the contents by this language.', 'mailin' ); ?>"
1657 data-html="true" class="fa fa-question-circle popover-help-form"></i>
1658 </div>
1659 <?php } ?>
1660 </div>
1661 </div>
1662 <?php
1663 }
1664 }
1665
1666 public function ajax_get_country_prefix() {
1667 check_ajax_referer( 'sib_front_ajax_nonce', 'security' );
1668 $sms_manager = new SIB_SMS_Code();
1669 $country_list = $sms_manager->get_sms_code_list();
1670 $country_list_html = '';
1671 foreach ( $country_list as $item => $value ) {
1672 $flg_url = plugins_url( 'img/flags/', __FILE__ ).strtolower($item).'.png';
1673 $item_html = '<li class="sib-country-prefix" data-country-code="'.$item.'" data-dial-code="'.$value["code"].'"><div class="sib-flag-box"><div class="sib-flag '.$item.'" style="background-image: url('.$flg_url.')"></div><span>'.$value['name'].'</span><span class="sib-dial-code">+'.$value['code'].'</span></div></li>';
1674 $country_list_html .= $item_html;
1675 }
1676 wp_send_json($country_list_html);
1677 }
1678
1679 /**
1680 * @param string $postAttribute
1681 * @param array $sibAttributes
1682 * @return null|string the corresponding sib attribute or null if not found
1683 */
1684 private function getCorrespondingSibAttribute($postAttribute, $sibAttributes)
1685 {
1686 $normalizedPostAttribute = strtoupper(sanitize_text_field($postAttribute));
1687 foreach ($sibAttributes as $sibAttribute) {
1688 if ($normalizedPostAttribute == strtoupper($sibAttribute)) {
1689 return $sibAttribute;
1690 }
1691 }
1692
1693 return null;
1694 }
1695
1696 public function my_upgrade_function() {
1697 $current_plugin_path_name = plugin_basename( __FILE__ );
1698 activate_plugin( $current_plugin_path_name );
1699 }
1700
1701
1702 public function brevo_wp_load()
1703 {
1704 $installationId = get_option( SIB_Manager::INSTALLATION_ID );
1705 $pluginVersion = get_option( SIB_Manager::BREVO_PLUGIN_VERSION );
1706 if(!empty($installationId) && (empty($pluginVersion) || $pluginVersion != SendinblueApiClient::PLUGIN_VERSION))
1707 {
1708 $apiClient = new SendinblueApiClient();
1709 $params["connection"] = 27;
1710 $params["plugin_version"] = SendinblueApiClient::PLUGIN_VERSION;
1711 $params["shop_version"] = get_bloginfo('version');
1712 $apiClient->updateInstallationInfo($installationId, $params);;
1713 if ( $apiClient->getLastResponseCode() === SendinblueApiClient::RESPONSE_CODE_NO_CONTENT )
1714 {
1715 update_option(SIB_Manager::BREVO_PLUGIN_VERSION, SendinblueApiClient::PLUGIN_VERSION);
1716 }
1717 }
1718 }
1719
1720 public static function wordpress_allowed_attributes()
1721 {
1722 global $allowedposttags, $allowedtags, $allowedentitynames;
1723 $attributes = [$allowedposttags, $allowedtags, $allowedentitynames, self::SIB_ATTRIBUTE];
1724 $attributes = call_user_func_array("array_merge", $attributes);
1725
1726 add_filter( 'safe_style_css', function($css_attr) {
1727 array_push($css_attr, 'display');
1728 return $css_attr;
1729 });
1730
1731 return $attributes;
1732 }
1733
1734 static function create_brevo_rest_endpoints() {
1735 $path = '/mailin_disconnect';
1736
1737 $arguments = array(
1738 self::ROUTE_METHODS => 'DELETE',
1739 self::ROUTE_CALLBACK => function ($request) {
1740 return self::mailin_disconnect($request);
1741 },
1742 self::PERMISSION_CALLBACK => '__return_true',
1743 );
1744
1745 register_rest_route("mailin/v1", $path, $arguments);
1746 }
1747
1748 private static function mailin_disconnect($request) {
1749 $request = $request->get_params();
1750 $user_connection_id = isset($request['id']) ? $request['id'] : '';
1751 if (!empty($user_connection_id)) {
1752 $installationId = get_option( SIB_Manager::INSTALLATION_ID );
1753
1754 if ($user_connection_id == $installationId) {
1755 self::delete_connection();
1756 } else {
1757 return new WP_REST_Response(
1758 array(
1759 'message' => "user_connection_id not found"
1760 ), 404);
1761 }
1762 }
1763 }
1764
1765 private static function delete_connection()
1766 {
1767 $setting = array();
1768 update_option( self::MAIN_OPTION_NAME, $setting );
1769 delete_option(self::API_KEY_V3_OPTION_NAME);
1770
1771 $home_settings = array(
1772 'activate_email' => 'no',
1773 'activate_ma' => 'default',
1774 );
1775 update_option( self::HOME_OPTION_NAME, $home_settings );
1776
1777 // remove sync users option.
1778 delete_option( 'sib_sync_users' );
1779 // remove all transients.
1780 SIB_API_Manager::remove_transients();
1781
1782 // remove all forms.
1783 SIB_Forms::removeAllForms();
1784 SIB_Forms_Lang::remove_all_trans();
1785 delete_option(SIB_Manager::INSTALLATION_ID);
1786 }
1787 }
1788
1789 add_action( 'sendinblue_init', 'sendinblue_init' );
1790 add_filter( 'widget_text', 'do_shortcode' );
1791
1792 /**
1793 * Plugin entry point Process.
1794 */
1795 function sendinblue_init() {
1796 SIB_Manager::LoadTextDomain();
1797 new SIB_Manager();
1798 }
1799
1800 do_action( 'sendinblue_init' );
1801 }
1802