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