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