/app/addon/mailchimp/class-ms-addon-mailchimp.php

  1. <?php 
  2. /** 
  3. * Add-On controller for: MailChimp 
  4. * 
  5. * @since 1.0.0 
  6. * 
  7. * @package Membership2 
  8. * @subpackage Controller 
  9. */ 
  10. class MS_Addon_Mailchimp extends MS_Addon { 
  11.  
  12. /** 
  13. * The Add-on ID 
  14. * 
  15. * @since 1.0.0 
  16. */ 
  17. const ID = 'mailchimp'; 
  18.  
  19. /** 
  20. * Mailchimp API object 
  21. * 
  22. * @var M2_Mailchimp 
  23. */ 
  24. static protected $mailchimp_api = null; 
  25.  
  26. /** 
  27. * Checks if the current Add-on is enabled 
  28. * 
  29. * @since 1.0.0 
  30. * @return bool 
  31. */ 
  32. static public function is_active() { 
  33. return MS_Model_Addon::is_enabled( self::ID ); 
  34.  
  35. /** 
  36. * Returns the Add-on ID (self::ID). 
  37. * 
  38. * @since 1.0.1.0 
  39. * @return string 
  40. */ 
  41. public function get_id() { 
  42. return self::ID; 
  43.  
  44. /** 
  45. * Initializes the Add-on. Always executed. 
  46. * 
  47. * @since 1.0.0 
  48. */ 
  49. public function init() { 
  50. if ( self::is_active() ) { 
  51. $this->add_filter( 
  52. 'ms_controller_settings_get_tabs',  
  53. 'settings_tabs',  
  54. 10, 2 
  55. ); 
  56.  
  57. $this->add_action( 
  58. 'ms_controller_settings_enqueue_scripts_' . self::ID,  
  59. 'enqueue_scripts' 
  60. ); 
  61.  
  62. $this->add_filter( 
  63. 'ms_view_settings_edit_render_callback',  
  64. 'manage_render_callback',  
  65. 10, 3 
  66. ); 
  67.  
  68. // Watch for REGISTER event: Subscribe user to list. 
  69. $this->add_action( 
  70. 'ms_model_event_'. MS_Model_Event::TYPE_MS_REGISTERED,  
  71. 'subscribe_registered',  
  72. 10, 2 
  73. ); 
  74.  
  75. // Watch for SIGN UP event: Subscribe user to list. 
  76. $this->add_action( 
  77. 'ms_model_event_'. MS_Model_Event::TYPE_MS_SIGNED_UP,  
  78. 'subscribe_members',  
  79. 10, 2 
  80. ); 
  81.  
  82. // Watch for DEACTIVATE event: Subscribe user to list. 
  83. $this->add_action( 
  84. 'ms_model_event_'. MS_Model_Event::TYPE_MS_DEACTIVATED,  
  85. 'subscribe_deactivated',  
  86. 10, 2 
  87. ); 
  88.  
  89. $this->add_filter( 
  90. 'ms_view_membership_details_tab',  
  91. 'mc_fields_for_ms',  
  92. 10, 3 
  93. ); 
  94.  
  95. $this->add_filter( 
  96. 'ms_view_membership_edit_to_html',  
  97. 'mc_custom_html',  
  98. 10, 3 
  99. ); 
  100.  
  101. $this->add_action( 
  102. 'ms_model_membership__set_after',  
  103. 'ms_model_membership__set_after_cb',  
  104. 10, 3 
  105. ); 
  106.  
  107. $this->add_action( 
  108. 'ms_model_membership__get',  
  109. 'ms_model_membership__get_cb',  
  110. 10, 3 
  111. ); 
  112.  
  113. /** 
  114. * Registers the Add-On 
  115. * 
  116. * @since 1.0.0 
  117. * @param array $list The Add-Ons list. 
  118. * @return array The updated Add-Ons list. 
  119. */ 
  120. public function register( $list ) { 
  121. $list[ self::ID ] = (object) array( 
  122. 'name' => __( 'MailChimp Integration', 'membership2' ),  
  123. 'description' => __( 'Enable MailChimp integration.', 'membership2' ),  
  124. 'icon' => 'dashicons dashicons-email',  
  125. ); 
  126.  
  127. return $list; 
  128.  
  129. /** 
  130. * A new user registered (not a Member yet). 
  131. * 
  132. * @since 1.0.0 
  133. * @param mixed $event 
  134. * @param mixed $member 
  135. */ 
  136. public function subscribe_registered( $event, $member ) { 
  137. try{ 
  138. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ) ) { 
  139. if ( ! self::is_user_subscribed( $member->email, $list_id ) ) { 
  140. self::subscribe_user( $member, $list_id ); 
  141. }catch( Exception $e ) { 
  142. MS_Helper_Debug::log( $e->getMessage() ); 
  143.  
  144. /** 
  145. * A user subscribed to a membership. 
  146. * 
  147. * @since 1.0.0 
  148. * @param mixed $event 
  149. * @param mixed $member 
  150. */ 
  151. public function subscribe_members( $event, $subscription ) { 
  152. try{ 
  153.  
  154. $member = $subscription->get_member(); 
  155.  
  156. $mail_list_registered = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ); 
  157. $mail_list_deactivated = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ); 
  158. $mail_list_members = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ); 
  159.  
  160. if( $mail_list_members != $mail_list_registered ) { 
  161. /** Verify if is subscribed to registered mail list and remove it. */ 
  162. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ) ) { 
  163. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  164. self::unsubscribe_user( $member->email, $list_id ); 
  165.  
  166. if( $mail_list_members != $mail_list_deactivated ) { 
  167. /** Verify if is subscribed to deactivated mail list and remove it. */ 
  168. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ) ) { 
  169. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  170. self::unsubscribe_user( $member->email, $list_id ); 
  171.  
  172. /** Subscribe to members mail list. */ 
  173. $custom_list_id = get_option( 'ms_mc_m_id_' . $subscription->membership_id ); 
  174.  
  175. if ( isset( $custom_list_id ) && 0 != $custom_list_id ) { 
  176. $list_id = $custom_list_id; 
  177. } else { 
  178. $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ); 
  179.  
  180. if ( $list_id ) { 
  181. if ( ! self::is_user_subscribed( $member->email, $list_id ) ) { 
  182. self::subscribe_user( $member, $list_id ); 
  183. }catch( Exception $e ) { 
  184. MS_Helper_Debug::log( $e->getMessage() ); 
  185.  
  186. /** 
  187. * A membership was deactivated (e.g. expired or manually cancelled) 
  188. * 
  189. * @since 1.0.0 
  190. * @param mixed $event 
  191. * @param mixed $member 
  192. */ 
  193. public function subscribe_deactivated( $event, $subscription ) { 
  194. try{ 
  195. $member = $subscription->get_member(); 
  196.  
  197. $mail_list_registered = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ); 
  198. $mail_list_deactivated = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ); 
  199. $mail_list_members = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ); 
  200.  
  201. if( $mail_list_deactivated == $mail_list_registered ) { 
  202. // Verify if is subscribed to registered mail list and remove it. 
  203. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ) ) { 
  204. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  205. self::unsubscribe_user( $member->email, $list_id ); 
  206.  
  207. if( $mail_list_deactivated == $mail_list_members ) { 
  208. // Verify if is subscribed to members mail list and remove it. 
  209. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ) ) { 
  210. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  211. self::unsubscribe_user( $member->email, $list_id ); 
  212.  
  213. // Subscribe to deactiveted members mail list. 
  214. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ) ) { 
  215. if ( ! self::is_user_subscribed( $member->email, $list_id ) ) { 
  216. self::subscribe_user( $member, $list_id ); 
  217. }catch( Exception $e ) { 
  218. MS_Helper_Debug::log( $e->getMessage() ); 
  219.  
  220. /** 
  221. * Add mailchimp settings tab in settings page. 
  222. * 
  223. * @since 1.0.0 
  224. * 
  225. * @filter ms_controller_membership_get_tabs 
  226. * 
  227. * @param array $tabs The current tabs. 
  228. * @param int $membership_id The membership id to edit 
  229. * @return array The filtered tabs. 
  230. */ 
  231. public function settings_tabs( $tabs ) { 
  232. $tabs[ self::ID ] = array( 
  233. 'title' => __( 'MailChimp', 'membership2' ),  
  234. 'url' => MS_Controller_Plugin::get_admin_url( 
  235. 'settings',  
  236. array( 'tab' => self::ID ) 
  237. ),  
  238. ); 
  239.  
  240. return $tabs; 
  241.  
  242. /** 
  243. * Enqueue admin scripts in the settings screen. 
  244. * 
  245. * @since 1.0.0 
  246. */ 
  247. public function enqueue_scripts() { 
  248. $data = array( 
  249. 'ms_init' => array( 'view_settings_mailchimp' ),  
  250. ); 
  251.  
  252. lib3()->ui->data( 'ms_data', $data ); 
  253. wp_enqueue_script( 'ms-admin' ); 
  254.  
  255. /** 
  256. * Add mailchimp views callback. 
  257. * 
  258. * @since 1.0.0 
  259. * 
  260. * @filter ms_view_settings_edit_render_callback 
  261. * 
  262. * @param array $callback The current function callback. 
  263. * @param string $tab The current membership rule tab. 
  264. * @param array $data The data shared to the view. 
  265. * @return array The filtered callback. 
  266. */ 
  267. public function manage_render_callback( $callback, $tab, $data ) { 
  268. if ( self::ID == $tab ) { 
  269. $view = MS_Factory::load( 'MS_Addon_Mailchimp_View' ); 
  270. $view->data = $data; 
  271. $callback = array( $view, 'render_tab' ); 
  272.  
  273. return $callback; 
  274.  
  275. /** 
  276. * Get mailchimp api lib status. 
  277. * 
  278. * @since 1.0.0 
  279. * 
  280. * @return boolean true on successfully loaded api, false otherwise. 
  281. */ 
  282. public static function get_api_status() { 
  283. $status = false; 
  284.  
  285. try { 
  286. self::load_mailchimp_api(); 
  287. $status = true; 
  288. } catch ( Exception $e ) { 
  289. MS_Helper_Debug::log( $e ); 
  290.  
  291. return $status; 
  292.  
  293. /** 
  294. * Load the Mailchimp API 
  295. * 
  296. * @since 1.0.0 
  297. * 
  298. * @return M2_Mailchimp Object 
  299. */ 
  300. public static function load_mailchimp_api() { 
  301. if ( empty( self::$mailchimp_api ) ) { 
  302. $options = apply_filters( 
  303. 'ms_addon_mailchimp_load_mailchimp_api_options',  
  304. array( 
  305. 'timeout' => false,  
  306. 'ssl_verifypeer' => false,  
  307. 'ssl_verifyhost' => false,  
  308. 'ssl_cainfo' => false,  
  309. 'debug' => false,  
  310. ); 
  311.  
  312. if ( ! class_exists( 'M2_Mailchimp' ) ) { 
  313. require_once MS_Plugin::instance()->dir . '/lib/mailchimp-api/Mailchimp.php'; 
  314.  
  315. $api = new M2_Mailchimp( 
  316. self::$settings->get_custom_setting( 'mailchimp', 'api_key' ),  
  317. $options 
  318. ); 
  319.  
  320. // Pinging the server 
  321. $ping = $api->helper->ping(); 
  322.  
  323. if ( is_wp_error( $ping ) ) { 
  324. throw new Exception( $ping ); 
  325.  
  326. self::$mailchimp_api = $api; 
  327.  
  328. return self::$mailchimp_api; 
  329.  
  330. /** 
  331. * Get the lists of a Mailchimp account. 
  332. * 
  333. * @return Array Lists info 
  334. */ 
  335. public static function get_mail_lists( $default = null ) { 
  336. static $Mail_lists = null; 
  337.  
  338. if ( null === $default ) { 
  339. $default = __( 'None', 'membership2' ); 
  340.  
  341. if ( null === $Mail_lists ) { 
  342. $Mail_lists = array( 0 => $default ); 
  343.  
  344. if ( self::get_api_status() ) { 
  345. $page = 0; 
  346. $items_per_page = 25; 
  347. $iterations = 0; 
  348.  
  349. do { 
  350. $lists = self::$mailchimp_api->lists->getList( 
  351. array(),  
  352. $page,  
  353. $items_per_page 
  354. ); 
  355.  
  356. $page += 1; 
  357. $iterations += 1; 
  358.  
  359. if ( is_wp_error( $lists ) ) { 
  360. $has_more = false; 
  361. MS_Helper_Debug::log( $lists ); 
  362. } else { 
  363. $has_more = count( $lists['data'] ) >= $items_per_page; 
  364. foreach ( $lists['data'] as $list ) { 
  365. $Mail_lists[ $list['id'] ] = $list['name']; 
  366.  
  367. // Force to exit the loop after max. 100 API calls (2500 lists). 
  368. if ( $iterations > 100 ) { 
  369. $has_more = false; 
  370. } while ( $has_more ); 
  371.  
  372. return $Mail_lists; 
  373.  
  374. /** 
  375. * Check if a user is subscribed in the list 
  376. * 
  377. * @param string $user_email 
  378. * @param string $list_id 
  379. * @return bool True if the user is subscribed already to the list 
  380. */ 
  381. public static function is_user_subscribed( $user_email, $list_id ) { 
  382. $subscribed = false; 
  383.  
  384. if ( is_email( $user_email ) && self::get_api_status() ) { 
  385. $emails = array( 
  386. array( 'email' => $user_email ),  
  387. ); 
  388.  
  389. $results = self::$mailchimp_api->lists->memberInfo( $list_id, $emails ); 
  390.  
  391. if ( is_wp_error( $results ) ) { 
  392. MS_Helper_Debug::log( $results ); 
  393. } elseif ( ! empty( $results['success_count'] ) 
  394. && ! empty( $results['data'][0]['status'] ) 
  395. && 'subscribed' == $results['data'][0]['status'] 
  396. ) { 
  397. $subscribed = true; 
  398.  
  399. return $subscribed; 
  400.  
  401. /** 
  402. * Subscribe a user to a Mailchimp list 
  403. * 
  404. * @since 1.0.0 
  405. * 
  406. * @param MS_Model_Member $member 
  407. * @param int $list_id 
  408. */ 
  409. public static function subscribe_user( $member, $list_id ) { 
  410. if ( is_email( $member->email ) && self::get_api_status() ) { 
  411. $auto_opt_in = self::$settings->get_custom_setting( 
  412. 'mailchimp',  
  413. 'auto_opt_in' 
  414. ); 
  415. $auto_opt_in = lib3()->is_true( $auto_opt_in ); 
  416.  
  417. $update = apply_filters( 
  418. 'ms_addon_mailchimp_subscribe_user_update',  
  419. true,  
  420. $member,  
  421. $list_id 
  422. ); 
  423.  
  424. $merge_vars = array(); 
  425. $merge_vars['FNAME'] = $member->first_name; 
  426. $merge_vars['LNAME'] = $member->last_name; 
  427.  
  428. if ( $auto_opt_in ) { 
  429. $merge_vars['optin_ip'] = $_SERVER['REMOTE_ADDR']; 
  430. $merge_vars['optin_time'] = MS_Helper_Period::current_time(); 
  431.  
  432. if ( empty( $merge_vars['FNAME'] ) ) { 
  433. unset( $merge_vars['FNAME'] ); 
  434. if ( empty( $merge_vars['LNAME'] ) ) { 
  435. unset( $merge_vars['LNAME'] ); 
  436.  
  437. $merge_vars = apply_filters( 
  438. 'ms_addon_mailchimp_subscribe_user_merge_vars',  
  439. $merge_vars,  
  440. $member,  
  441. $list_id 
  442. ); 
  443.  
  444. $email_field = array( 'email' => $member->email ); 
  445.  
  446. $res = self::$mailchimp_api->lists->subscribe( 
  447. $list_id,  
  448. $email_field,  
  449. $merge_vars,  
  450. 'html',  
  451. ( ! $auto_opt_in ),  
  452. $update 
  453. ); 
  454.  
  455. if( ! $res ) { 
  456. echo self::$mailchimp_api->errorMessage(); 
  457.  
  458. /** 
  459. * Update a user data in a list 
  460. * 
  461. * @since 1.0.0 
  462. * 
  463. * @param string $user_email 
  464. * @param string $list_id 
  465. * @param array $merge_vars { 
  466. * $FNAME => First name 
  467. * $LNAME => Last Name 
  468. * } 
  469. */ 
  470. public static function update_user( $user_email, $list_id, $merge_vars ) { 
  471. if ( self::get_api_status() ) { 
  472. $merge_vars['update_existing'] = true; 
  473.  
  474. return self::$mailchimp_api->lists->updateMember( 
  475. $list_id,  
  476. array( 'email' => $user_email ),  
  477. $merge_vars 
  478. ); 
  479.  
  480. /** 
  481. * Unsubscribe a user from a list 
  482. * 
  483. * @param string $user_email 
  484. * @param string $list_id 
  485. * @param bool $delete True if the user is gonna be deleted from the list (not only unsubscribed) 
  486. */ 
  487. public static function unsubscribe_user( $user_email, $list_id, $delete = false ) { 
  488. if ( self::get_api_status() ) { 
  489. return self::$mailchimp_api->lists->unsubscribe( 
  490. $list_id,  
  491. array( 'email' => $user_email ),  
  492. $delete 
  493. ); 
  494.  
  495. /** 
  496. * Add additional field to show a list of mailchimp list 
  497. * 
  498. * @since 1.0.3.0 
  499. */ 
  500. public function mc_fields_for_ms( $fields, $membership, $data ) { 
  501.  
  502. $mail_list = self::get_mail_lists( __( 'Default', 'membership2' ) ); 
  503.  
  504. $fields['ms_mc'] = array( 
  505. 'id' => 'ms_mc',  
  506. 'type' => MS_Helper_Html::INPUT_TYPE_SELECT,  
  507. 'title' => __( 'Mailchimp List', 'membership2' ),  
  508. 'desc' => __( 'You can select a list for this membership.', 'membership2' ),  
  509. 'class' => 'ms-mc',  
  510. 'before' => __( 'Select a list', 'membership2' ),  
  511. 'value' => $membership->ms_mc,  
  512. 'field_options' => $mail_list,  
  513. 'ajax_data' => array( 1 ),  
  514. ); 
  515.  
  516. return $fields; 
  517.  
  518.  
  519. /** 
  520. * Modify the edit membership basic settings page 
  521. * 
  522. * @since 1.0.3.0 
  523. */ 
  524. public function mc_custom_html( $html, $field, $membership ) { 
  525. ob_start(); 
  526. ?> 
  527. <div> 
  528. <form class="ms-form wpmui-ajax-update ms-edit-membership" data-wpmui-ajax="<?php echo esc_attr( 'save' ); ?>"> 
  529. <div class="ms-form wpmui-form wpmui-grid-8"> 
  530. <div class="col-5"> 
  531. <?php 
  532. MS_Helper_Html::html_element( $field['name'] ); 
  533. if ( ! $membership->is_system() ) { 
  534. MS_Helper_Html::html_element( $field['description'] ); 
  535. ?> 
  536. </div> 
  537. <div class="col-3"> 
  538. <?php 
  539. MS_Helper_Html::html_element( $field['active'] ); 
  540. if ( ! $membership->is_system() ) { 
  541. MS_Helper_Html::html_element( $field['public'] ); 
  542. MS_Helper_Html::html_element( $field['paid'] ); 
  543. ?> 
  544. </div> 
  545. </div> 
  546. <div class="ms-form wpmui-form wpmui-grid-8"> 
  547. <div class="col-8"> 
  548. <?php 
  549. if ( ! $membership->is_system() ) { 
  550. MS_Helper_Html::html_element( $field['priority'] ); 
  551. echo '<hr>'; 
  552. MS_Helper_Html::html_element( $field['ms_mc'] ); 
  553. ?> 
  554. </div> 
  555. </div> 
  556. </form> 
  557. </div> 
  558. <?php 
  559. $output = ob_get_clean(); 
  560.  
  561. return $output; 
  562.  
  563. /** 
  564. * Save custom list for individual membership 
  565. * 
  566. * @since 1.0.3.0 
  567. */ 
  568. public function ms_model_membership__set_after_cb( $property, $value, $membership ) { 
  569. if ( 'ms_mc' == $property ) { 
  570. update_option( 'ms_mc_m_id_' . $membership->id, $value ); 
  571.  
  572. /** 
  573. * Retrieve custom list for indiviaul membership 
  574. * 
  575. * @since 1.0.3.0 
  576. */ 
  577. public function ms_model_membership__get_cb( $value, $property, $membership ) { 
  578. if ( 'ms_mc' == $property ) { 
  579. return get_option( 'ms_mc_m_id_' . $membership->id ); 
  580.  
  581. return $value; 
.