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