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