/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. $member = $subscription->get_member(); 
  154.  
  155. $mail_list_registered = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ); 
  156. $mail_list_deactivated = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ); 
  157. $mail_list_members = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ); 
  158.  
  159. if ( $mail_list_members != $mail_list_registered ) { 
  160. /** Verify if is subscribed to registered mail list and remove it. */ 
  161. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ) ) { 
  162. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  163. self::unsubscribe_user( $member->email, $list_id ); 
  164.  
  165. if ( $mail_list_members != $mail_list_deactivated ) { 
  166. /** Verify if is subscribed to deactivated mail list and remove it. */ 
  167. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ) ) { 
  168. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  169. self::unsubscribe_user( $member->email, $list_id ); 
  170.  
  171. /** Subscribe to members mail list. */ 
  172. $custom_list_id = get_option( 'ms_mc_m_id_' . $subscription->membership_id ); 
  173.  
  174. if ( isset( $custom_list_id ) && 0 != $custom_list_id ) { 
  175. $list_id = $custom_list_id; 
  176. } else { 
  177. $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ); 
  178.  
  179. if ( $list_id ) { 
  180. if ( ! self::is_user_subscribed( $member->email, $list_id ) ) { 
  181. self::subscribe_user( $member, $list_id ); 
  182. } catch ( Exception $e ) { 
  183. // MS_Helper_Debug::log( $e->getMessage() ); 
  184.  
  185. /** 
  186. * A membership was deactivated (e.g. expired or manually cancelled) 
  187. * 
  188. * @since 1.0.0 
  189. * @param mixed $event 
  190. * @param mixed $member 
  191. */ 
  192. public function subscribe_deactivated( $event, $subscription ) { 
  193. try { 
  194. $member = $subscription->get_member(); 
  195.  
  196. $mail_list_registered = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ); 
  197. $mail_list_deactivated = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ); 
  198. $mail_list_members = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ); 
  199.  
  200. if ( $mail_list_deactivated == $mail_list_registered ) { 
  201. // Verify if is subscribed to registered mail list and remove it. 
  202. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_registered' ) ) { 
  203. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  204. self::unsubscribe_user( $member->email, $list_id ); 
  205.  
  206. if ( $mail_list_deactivated == $mail_list_members ) { 
  207. // Verify if is subscribed to members mail list and remove it. 
  208. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_members' ) ) { 
  209. if ( self::is_user_subscribed( $member->email, $list_id ) ) { 
  210. self::unsubscribe_user( $member->email, $list_id ); 
  211.  
  212. // Subscribe to deactiveted members mail list. 
  213. if ( $list_id = self::$settings->get_custom_setting( 'mailchimp', 'mail_list_deactivated' ) ) { 
  214. if ( ! self::is_user_subscribed( $member->email, $list_id ) ) { 
  215. self::subscribe_user( $member, $list_id ); 
  216. } catch ( Exception $e ) { 
  217. // MS_Helper_Debug::log( $e->getMessage() ); 
  218.  
  219. /** 
  220. * Add mailchimp settings tab in settings page. 
  221. * 
  222. * @since 1.0.0 
  223. * 
  224. * @filter ms_controller_membership_get_tabs 
  225. * 
  226. * @param array $tabs The current tabs. 
  227. * @param int $membership_id The membership id to edit 
  228. * @return array The filtered tabs. 
  229. */ 
  230. public function settings_tabs( $tabs ) { 
  231. $tabs[ self::ID ] = array( 
  232. 'title' => __( 'MailChimp', 'membership2' ),  
  233. 'url' => MS_Controller_Plugin::get_admin_url( 
  234. 'settings',  
  235. array( 'tab' => self::ID ) 
  236. ),  
  237. ); 
  238.  
  239. return $tabs; 
  240.  
  241. /** 
  242. * Enqueue admin scripts in the settings screen. 
  243. * 
  244. * @since 1.0.0 
  245. */ 
  246. public function enqueue_scripts() { 
  247. $data = array( 
  248. 'ms_init' => array( 'view_settings_mailchimp' ),  
  249. ); 
  250.  
  251. lib3()->ui->data( 'ms_data', $data ); 
  252. wp_enqueue_script( 'ms-admin' ); 
  253.  
  254. /** 
  255. * Add mailchimp views callback. 
  256. * 
  257. * @since 1.0.0 
  258. * 
  259. * @filter ms_view_settings_edit_render_callback 
  260. * 
  261. * @param array $callback The current function callback. 
  262. * @param string $tab The current membership rule tab. 
  263. * @param array $data The data shared to the view. 
  264. * @return array The filtered callback. 
  265. */ 
  266. public function manage_render_callback( $callback, $tab, $data ) { 
  267. if ( self::ID == $tab ) { 
  268. $view = MS_Factory::load( 'MS_Addon_Mailchimp_View' ); 
  269. $view->data = $data; 
  270. $callback = array( $view, 'render_tab' ); 
  271.  
  272. return $callback; 
  273.  
  274. /** 
  275. * Get mailchimp api lib status. 
  276. * 
  277. * @since 1.0.0 
  278. * 
  279. * @return boolean true on successfully loaded api, false otherwise. 
  280. */ 
  281. public static function get_api_status() { 
  282. $status = false; 
  283.  
  284. try { 
  285. self::load_mailchimp_api(); 
  286. $status = true; 
  287. } catch ( Exception $e ) { 
  288. // MS_Helper_Debug::log( $e ); 
  289.  
  290. return $status; 
  291.  
  292. /** 
  293. * Load the Mailchimp API 
  294. * 
  295. * @since 1.0.0 
  296. * 
  297. * @return M2_Mailchimp Object 
  298. */ 
  299. public static function load_mailchimp_api() { 
  300. if ( empty( self::$mailchimp_api ) ) { 
  301. $options = apply_filters( 
  302. 'ms_addon_mailchimp_load_mailchimp_api_options',  
  303. array( 
  304. 'timeout' => false,  
  305. 'ssl_verifypeer' => false,  
  306. 'ssl_verifyhost' => false,  
  307. 'ssl_cainfo' => false,  
  308. 'debug' => false,  
  309. ); 
  310.  
  311. if ( ! class_exists( 'M2_Mailchimp' ) ) { 
  312. require_once MS_Plugin::instance()->dir . '/lib/mailchimp-api/Mailchimp.php'; 
  313.  
  314. $api = new M2_Mailchimp( 
  315. self::$settings->get_custom_setting( 'mailchimp', 'api_key' ),  
  316. $options 
  317. ); 
  318.  
  319. // Pinging the server 
  320. $ping = $api->helper->ping(); 
  321.  
  322. if ( is_wp_error( $ping ) ) { 
  323. throw new Exception( $ping ); 
  324.  
  325. self::$mailchimp_api = $api; 
  326.  
  327. return self::$mailchimp_api; 
  328.  
  329. /** 
  330. * Get the lists of a Mailchimp account. 
  331. * 
  332. * @return Array Lists info 
  333. */ 
  334. public static function get_mail_lists( $default = null ) { 
  335. static $Mail_lists = null; 
  336.  
  337. if ( null === $default ) { 
  338. $default = __( 'None', 'membership2' ); 
  339.  
  340. if ( null === $Mail_lists ) { 
  341. $Mail_lists = array( 0 => $default ); 
  342.  
  343. if ( self::get_api_status() ) { 
  344. $page = 0; 
  345. $items_per_page = 25; 
  346. $iterations = 0; 
  347.  
  348. do { 
  349. $lists = self::$mailchimp_api->lists->getList( 
  350. array(),  
  351. $page,  
  352. $items_per_page 
  353. ); 
  354.  
  355. $page += 1; 
  356. $iterations += 1; 
  357.  
  358. if ( is_wp_error( $lists ) ) { 
  359. $has_more = false; 
  360. // MS_Helper_Debug::log( $lists ); 
  361. } else { 
  362. $has_more = count( $lists['data'] ) >= $items_per_page; 
  363. foreach ( $lists['data'] as $list ) { 
  364. $Mail_lists[ $list['id'] ] = $list['name']; 
  365.  
  366. // Force to exit the loop after max. 100 API calls (2500 lists). 
  367. if ( $iterations > 100 ) { 
  368. $has_more = false; 
  369. } while ( $has_more ); 
  370.  
  371. return $Mail_lists; 
  372.  
  373. /** 
  374. * Check if a user is subscribed in the list 
  375. * 
  376. * @param string $user_email 
  377. * @param string $list_id 
  378. * @return bool True if the user is subscribed already to the list 
  379. */ 
  380. public static function is_user_subscribed( $user_email, $list_id ) { 
  381. $subscribed = false; 
  382.  
  383. if ( is_email( $user_email ) && self::get_api_status() ) { 
  384. $emails = array( 
  385. array( 'email' => $user_email ),  
  386. ); 
  387.  
  388. $results = self::$mailchimp_api->lists->memberInfo( $list_id, $emails ); 
  389.  
  390. if ( is_wp_error( $results ) ) { 
  391. // MS_Helper_Debug::log( $results ); 
  392. } elseif ( ! empty( $results['success_count'] ) 
  393. && ! empty( $results['data'][0]['status'] ) 
  394. && 'subscribed' == $results['data'][0]['status'] 
  395. ) { 
  396. $subscribed = true; 
  397.  
  398. return $subscribed; 
  399.  
  400. /** 
  401. * Subscribe a user to a Mailchimp list 
  402. * 
  403. * @since 1.0.0 
  404. * 
  405. * @param MS_Model_Member $member 
  406. * @param int $list_id 
  407. */ 
  408. public static function subscribe_user( $member, $list_id ) { 
  409. if ( is_email( $member->email ) && self::get_api_status() ) { 
  410. $auto_opt_in = self::$settings->get_custom_setting( 
  411. 'mailchimp',  
  412. 'auto_opt_in' 
  413. ); 
  414. $auto_opt_in = lib3()->is_true( $auto_opt_in ); 
  415.  
  416. $update = apply_filters( 
  417. 'ms_addon_mailchimp_subscribe_user_update',  
  418. true,  
  419. $member,  
  420. $list_id 
  421. ); 
  422.  
  423. $merge_vars = array(); 
  424. $merge_vars['FNAME'] = $member->first_name; 
  425. $merge_vars['LNAME'] = $member->last_name; 
  426.  
  427. if ( $auto_opt_in ) { 
  428. $merge_vars['optin_ip'] = $_SERVER['REMOTE_ADDR']; 
  429. $merge_vars['optin_time'] = MS_Helper_Period::current_time(); 
  430.  
  431. if ( empty( $merge_vars['FNAME'] ) ) { 
  432. unset( $merge_vars['FNAME'] ); 
  433. if ( empty( $merge_vars['LNAME'] ) ) { 
  434. unset( $merge_vars['LNAME'] ); 
  435.  
  436. $merge_vars = apply_filters( 
  437. 'ms_addon_mailchimp_subscribe_user_merge_vars',  
  438. $merge_vars,  
  439. $member,  
  440. $list_id 
  441. ); 
  442.  
  443. $email_field = array( 'email' => $member->email ); 
  444.  
  445. $res = self::$mailchimp_api->lists->subscribe( 
  446. $list_id,  
  447. $email_field,  
  448. $merge_vars,  
  449. 'html',  
  450. ( ! $auto_opt_in ),  
  451. $update 
  452. ); 
  453.  
  454. if ( ! $res ) { 
  455. echo self::$mailchimp_api->errorMessage(); 
  456.  
  457. /** 
  458. * Update a user data in a list 
  459. * 
  460. * @since 1.0.0 
  461. * 
  462. * @param string $user_email 
  463. * @param string $list_id 
  464. * @param array $merge_vars { 
  465. * $FNAME => First name 
  466. * $LNAME => Last Name 
  467. * } 
  468. */ 
  469. public static function update_user( $user_email, $list_id, $merge_vars ) { 
  470. if ( self::get_api_status() ) { 
  471. $merge_vars['update_existing'] = true; 
  472.  
  473. return self::$mailchimp_api->lists->updateMember( 
  474. $list_id,  
  475. array( 'email' => $user_email ),  
  476. $merge_vars 
  477. ); 
  478.  
  479. /** 
  480. * Unsubscribe a user from a list 
  481. * 
  482. * @param string $user_email 
  483. * @param string $list_id 
  484. * @param bool $delete True if the user is gonna be deleted from the list (not only unsubscribed) 
  485. */ 
  486. public static function unsubscribe_user( $user_email, $list_id, $delete = false ) { 
  487. if ( self::get_api_status() ) { 
  488. return self::$mailchimp_api->lists->unsubscribe( 
  489. $list_id,  
  490. array( 'email' => $user_email ),  
  491. $delete 
  492. ); 
  493.  
  494. /** 
  495. * Add additional field to show a list of mailchimp list 
  496. * 
  497. * @since 1.0.3.0 
  498. */ 
  499. public function mc_fields_for_ms( $fields, $membership, $data ) { 
  500.  
  501. $mail_list = self::get_mail_lists( __( 'Default', 'membership2' ) ); 
  502.  
  503. $fields['ms_mc'] = array( 
  504. 'id' => 'ms_mc',  
  505. 'type' => MS_Helper_Html::INPUT_TYPE_SELECT,  
  506. 'title' => __( 'Mailchimp List', 'membership2' ),  
  507. 'desc' => __( 'You can select a list for this membership.', 'membership2' ),  
  508. 'class' => 'ms-mc',  
  509. 'before' => __( 'Select a list', 'membership2' ),  
  510. 'value' => $membership->ms_mc,  
  511. 'field_options' => $mail_list,  
  512. 'ajax_data' => array( 1 ),  
  513. ); 
  514.  
  515. return $fields; 
  516.  
  517.  
  518. /** 
  519. * Modify the edit membership basic settings page 
  520. * 
  521. * @since 1.0.3.0 
  522. */ 
  523. public function mc_custom_html( $html, $field, $membership ) { 
  524. ob_start(); 
  525. ?> 
  526. <div> 
  527. <form class="ms-form wpmui-ajax-update ms-edit-membership" data-wpmui-ajax="<?php echo esc_attr( 'save' ); ?>"> 
  528. <div class="ms-form wpmui-form wpmui-grid-8"> 
  529. <div class="col-5"> 
  530. <?php 
  531. MS_Helper_Html::html_element( $field['name'] ); 
  532. if ( ! $membership->is_system() ) { 
  533. MS_Helper_Html::html_element( $field['description'] ); 
  534. ?> 
  535. </div> 
  536. <div class="col-3"> 
  537. <?php 
  538. MS_Helper_Html::html_element( $field['active'] ); 
  539. if ( ! $membership->is_system() ) { 
  540. MS_Helper_Html::html_element( $field['public'] ); 
  541. MS_Helper_Html::html_element( $field['paid'] ); 
  542. ?> 
  543. </div> 
  544. </div> 
  545. <div class="ms-form wpmui-form wpmui-grid-8"> 
  546. <div class="col-8"> 
  547. <?php 
  548. if ( ! $membership->is_system() ) { 
  549. MS_Helper_Html::html_element( $field['priority'] ); 
  550. echo '<hr>'; 
  551. MS_Helper_Html::html_element( $field['ms_mc'] ); 
  552. ?> 
  553. </div> 
  554. </div> 
  555. </form> 
  556. </div> 
  557. <?php 
  558. $output = ob_get_clean(); 
  559.  
  560. return $output; 
  561.  
  562. /** 
  563. * Save custom list for individual membership 
  564. * 
  565. * @since 1.0.3.0 
  566. */ 
  567. public function ms_model_membership__set_after_cb( $property, $value, $membership ) { 
  568. if ( 'ms_mc' == $property ) { 
  569. update_option( 'ms_mc_m_id_' . $membership->id, $value ); 
  570.  
  571. /** 
  572. * Retrieve custom list for indiviaul membership 
  573. * 
  574. * @since 1.0.3.0 
  575. */ 
  576. public function ms_model_membership__get_cb( $value, $property, $membership ) { 
  577. if ( 'ms_mc' == $property ) { 
  578. return get_option( 'ms_mc_m_id_' . $membership->id ); 
  579.  
  580. return $value; 
.