/app/controller/class-ms-controller-communication.php

  1. <?php 
  2. /** 
  3. * Controller for Automated Communications. 
  4. * 
  5. * @since 1.0.0 
  6. * @package Membership2 
  7. * @subpackage Controller 
  8. */ 
  9. class MS_Controller_Communication extends MS_Controller { 
  10.  
  11. /** 
  12. * Ajax action name. 
  13. * 
  14. * @since 1.0.0 
  15. * @var string The ajax action name. 
  16. */ 
  17. const AJAX_ACTION_UPDATE_COMM = 'update_comm'; 
  18.  
  19. /** 
  20. * Save communication form. 
  21. * 
  22. * @since 1.0.1.0 
  23. * @var string 
  24. */ 
  25. const ACTION_SAVE_COMM = 'save_comm'; 
  26.  
  27. /** 
  28. * Prepare Membership settings manager. 
  29. * 
  30. * @since 1.0.0 
  31. */ 
  32. public function __construct() { 
  33. parent::__construct(); 
  34.  
  35. do_action( 'ms_controller_communication_before', $this ); 
  36.  
  37. $this->add_ajax_action( 
  38. self::AJAX_ACTION_UPDATE_COMM,  
  39. 'ajax_action_update_communication' 
  40. ); 
  41.  
  42. $this->add_action( 
  43. 'ms_controller_membership_setup_completed',  
  44. 'auto_setup_communications' 
  45. ); 
  46.  
  47. $this->add_action( 
  48. 'ms_model_event',  
  49. 'process_event',  
  50. 10, 2 
  51. ); 
  52.  
  53. $this->add_action( 
  54. 'ms_cron_process_communications',  
  55. 'process_queue' 
  56. ); 
  57.  
  58. do_action( 'ms_controller_communication_after', $this ); 
  59.  
  60. /** 
  61. * Initialize the admin-side functions. 
  62. * 
  63. * @since 1.0.0 
  64. */ 
  65. public function admin_init() { 
  66. $tab = ''; 
  67. if ( isset( $_GET['tab'] ) ) { 
  68. $tab = $_GET['tab']; 
  69.  
  70. /** 
  71. * Both in the Settings page and in the Membership Edit page the 
  72. * communication tab has the same name ('emails'), so we can use this 
  73. * info to better set-up our action hook. 
  74. */ 
  75. if ( MS_Controller_Settings::TAB_EMAILS == $tab ) { 
  76. $this->run_action( 
  77. 'init',  
  78. 'admin_manager' 
  79. ); 
  80.  
  81. // Add custom buttons to the MCE editor (insert variable). 
  82. $this->run_action( 
  83. 'admin_head',  
  84. 'add_mce_buttons' 
  85. ); 
  86.  
  87. /** 
  88. * Manages communication actions. 
  89. * 
  90. * Verifies GET and POST requests to manage settings. 
  91. * 
  92. * @since 1.0.1.0 
  93. */ 
  94. public function admin_manager() { 
  95. $msg = 0; 
  96. $redirect = false; 
  97.  
  98. if ( $this->is_admin_user() && $this->verify_nonce() ) { 
  99. /** 
  100. * After verifying permissions this filters can be used by Add-ons 
  101. * to process their own settings. 
  102. * 
  103. * @since 1.0.1.0 
  104. */ 
  105. do_action( 'ms_admin_communication_manager' ); 
  106.  
  107. $fields = array( 'type', 'subject', 'email_body' ); 
  108.  
  109. if ( self::validate_required( array( 'comm_type' ) ) 
  110. && MS_Model_Communication::is_valid_communication_type( $_POST['comm_type'] ) 
  111. ) { 
  112. // Load comm type from user select. 
  113. $redirect = esc_url_raw( 
  114. remove_query_arg( 
  115. 'msg',  
  116. add_query_arg( 'comm_type', $_POST['comm_type'] ) 
  117. ); 
  118. } elseif ( isset( $_POST['save_email'] ) 
  119. && self::validate_required( $fields ) 
  120. ) { 
  121. // Save email template form. 
  122. $default_type = MS_Model_Communication::COMM_TYPE_REGISTRATION; 
  123. if ( ! empty( $_REQUEST['membership_id'] ) ) { 
  124. $membership_id = intval( $_REQUEST['membership_id'] ); 
  125. $comm_types = array_keys( 
  126. MS_Model_Communication::get_communication_type_titles( 
  127. $membership_id 
  128. ); 
  129. $default_type = reset( $comm_types ); 
  130.  
  131. if ( ! empty( $_POST['type'] ) 
  132. && MS_Model_Communication::is_valid_communication_type( $_POST['type'] ) 
  133. ) { 
  134. $type = $_POST['type']; 
  135. } else { 
  136. $type = $default_type; 
  137.  
  138. $msg = $this->save_communication( $type, $_POST ); 
  139. $redirect = esc_url_raw( 
  140. add_query_arg( 
  141. array( 
  142. 'comm_type' => urlencode( $_POST['type'] ),  
  143. 'msg' => $msg,  
  144. ); 
  145.  
  146. if ( $redirect ) { 
  147. wp_safe_redirect( $redirect ); 
  148. exit(); 
  149.  
  150. /** 
  151. * Handles an event and process the correct communication if required. 
  152. * 
  153. * @since 1.0.1.0 
  154. * @param MS_Model_Event $event The event that is processed. 
  155. * @param mixed $data The data passed to the event handler. 
  156. */ 
  157. public function process_event( $event, $data ) { 
  158. if ( $data instanceof MS_Model_Relationship ) { 
  159. $subscription = $data; 
  160. $membership = $data->get_membership(); 
  161. } elseif ( $data instanceof MS_Model_Membership ) { 
  162. $subscription = false; 
  163. $membership = $data; 
  164. } else { 
  165. $subscription = false; 
  166. $membership = false; 
  167.  
  168. $enqueue = array(); 
  169. $process = array(); 
  170.  
  171. switch ( $event->type ) { 
  172. case MS_Model_Event::TYPE_MS_CANCELED: 
  173. $enqueue[] = MS_Model_Communication::COMM_TYPE_CANCELLED; 
  174. break; 
  175.  
  176. case MS_Model_Event::TYPE_CREDIT_CARD_EXPIRE: 
  177. $enqueue[] = MS_Model_Communication::COMM_TYPE_CREDIT_CARD_EXPIRE; 
  178. break; 
  179.  
  180. case MS_Model_Event::TYPE_PAYMENT_FAILED: 
  181. $enqueue[] = MS_Model_Communication::COMM_TYPE_FAILED_PAYMENT; 
  182. break; 
  183.  
  184. case MS_Model_Event::TYPE_MS_DEACTIVATED: 
  185. $enqueue[] = MS_Model_Communication::COMM_TYPE_FINISHED; 
  186. break; 
  187.  
  188. case MS_Model_Event::TYPE_UPDATED_INFO: 
  189. $enqueue[] = MS_Model_Communication::COMM_TYPE_INFO_UPDATE; 
  190. break; 
  191.  
  192. case MS_Model_Event::TYPE_PAID: 
  193. $enqueue[] = MS_Model_Communication::COMM_TYPE_INVOICE; 
  194. break; 
  195.  
  196. case MS_Model_Event::TYPE_MS_SIGNED_UP: 
  197. $process[] = MS_Model_Communication::COMM_TYPE_REGISTRATION_FREE; 
  198. $process[] = MS_Model_Communication::COMM_TYPE_REGISTRATION; 
  199. break; 
  200.  
  201. case MS_Model_Event::TYPE_MS_RENEWED: 
  202. $process[] = MS_Model_Communication::COMM_TYPE_RENEWED; 
  203. break; 
  204.  
  205. case MS_Model_Event::TYPE_MS_REGISTERED: 
  206. $process[] = MS_Model_Communication::COMM_TYPE_SIGNUP; 
  207. break; 
  208.  
  209. case MS_Model_Event::TYPE_MS_RESETPASSWORD: 
  210. $process[] = MS_Model_Communication::COMM_TYPE_RESETPASSWORD; 
  211. break; 
  212.  
  213. case MS_Model_Event::TYPE_MS_MOVED: 
  214. break; 
  215. case MS_Model_Event::TYPE_MS_EXPIRED: 
  216. break; 
  217. case MS_Model_Event::TYPE_MS_TRIAL_EXPIRED: 
  218. break; 
  219. case MS_Model_Event::TYPE_MS_DROPPED: 
  220. break; 
  221. case MS_Model_Event::TYPE_MS_BEFORE_FINISHES: 
  222. break; 
  223. case MS_Model_Event::TYPE_MS_AFTER_FINISHES: 
  224. break; 
  225. case MS_Model_Event::TYPE_MS_BEFORE_TRIAL_FINISHES: 
  226. break; 
  227. case MS_Model_Event::TYPE_MS_TRIAL_FINISHED: 
  228. break; 
  229. case MS_Model_Event::TYPE_PAYMENT_PENDING: 
  230. break; 
  231. case MS_Model_Event::TYPE_PAYMENT_DENIED: 
  232. break; 
  233. case MS_Model_Event::TYPE_PAYMENT_BEFORE_DUE: 
  234. break; 
  235. case MS_Model_Event::TYPE_PAYMENT_AFTER_DUE: 
  236. break; 
  237.  
  238. foreach ( $enqueue as $type ) { 
  239. $comm = MS_Model_Communication::get_communication( $type, $membership ); 
  240. if ( ! $comm ) { continue; } 
  241. $comm->enqueue_messages( $event, $data ); 
  242.  
  243. foreach ( $process as $type ) { 
  244. $comm = MS_Model_Communication::get_communication( $type, $membership ); 
  245. if ( ! $comm ) { continue; } 
  246. $comm->process_communication( $event, $data ); 
  247.  
  248. /** 
  249. * Send enqueued emails now. 
  250. * 
  251. * @since 1.0.1.0 
  252. * @internal Cron handler 
  253. * @see filter ms_cron_process_communications 
  254. */ 
  255. public function process_queue() { 
  256. $comms = MS_Model_Communication::get_communications( null ); 
  257.  
  258. foreach ( $comms as $comm ) { 
  259. $comm->process_queue(); 
  260.  
  261. /** 
  262. * Handle Ajax update comm field action. 
  263. * 
  264. * Related Action Hooks: 
  265. * - wp_ajax_update_comm 
  266. * 
  267. * @since 1.0.0 
  268. */ 
  269. public function ajax_action_update_communication() { 
  270. do_action( 
  271. 'ms_controller_communication_ajax_action_update_communication_before',  
  272. $this 
  273. ); 
  274.  
  275. $msg = MS_Helper_Settings::SETTINGS_MSG_NOT_UPDATED; 
  276.  
  277. $isset = array( 'type', 'field', 'value' ); 
  278. if ( $this->verify_nonce() 
  279. && self::validate_required( $isset, 'POST', false ) 
  280. && $this->is_admin_user() 
  281. ) { 
  282. lib3()->array->strip_slashes( $_POST, 'value' ); 
  283.  
  284. $membership_id = null; 
  285. if ( isset( $_POST['membership_id'] ) ) { 
  286. $membership_id = intval( $_POST['membership_id'] ); 
  287. $type = $_POST['type']; 
  288. $field = $_POST['field']; 
  289. $value = $_POST['value']; 
  290.  
  291. $comm = MS_Model_Communication::get_communication( 
  292. $type,  
  293. $membership_id,  
  294. true 
  295. ); 
  296.  
  297. $comm->$field = $value; 
  298. $comm->save(); 
  299. $msg = MS_Helper_Settings::SETTINGS_MSG_UPDATED; 
  300.  
  301. do_action( 
  302. 'ms_controller_communication_ajax_action_update_communication_after',  
  303. $this 
  304. ); 
  305.  
  306. echo apply_filters( 
  307. 'ms_controller_commnucation_ajax_action_update_communication_msg',  
  308. $msg,  
  309. $this 
  310. ); 
  311. exit; 
  312.  
  313. /** 
  314. * Auto setup communications. 
  315. * 
  316. * Fires after a membership setup is completed. 
  317. * 
  318. * Related Action Hooks: 
  319. * - ms_controller_membership_setup_completed 
  320. * 
  321. * @since 1.0.0 
  322. * @param MS_Model_Membership $membership 
  323. */ 
  324. public function auto_setup_communications( $membership ) { 
  325. /** 
  326. * Note: We intentionally set the parameter to 0. This 
  327. * function should set up default messages when first membership is 
  328. * created. It should not override default messages with membership- 
  329. * specific ones. 
  330. */ 
  331. $comms = MS_Model_Communication::get_communications( 0 ); 
  332.  
  333. foreach ( $comms as $comm ) { 
  334. $comm->enabled = true; 
  335. $comm->save(); 
  336.  
  337. do_action( 
  338. 'ms_controller_communication_auto_setup_communications_after',  
  339. $membership,  
  340. $this 
  341. ); 
  342.  
  343. /** 
  344. * Handle saving of Communication settings. 
  345. * 
  346. * @since 1.0.0 
  347. * 
  348. * @param mixed[] $fields The data to process. 
  349. */ 
  350. public function save_communication( $type, $fields ) { 
  351. $msg = MS_Helper_Settings::SETTINGS_MSG_NOT_UPDATED; 
  352.  
  353. if ( ! $this->is_admin_user() ) { 
  354. return $msg; 
  355.  
  356. $membership_id = null; 
  357. if ( isset( $_POST['membership_id'] ) ) { 
  358. $membership_id = intval( $_POST['membership_id'] ); 
  359.  
  360. $comm = MS_Model_Communication::get_communication( 
  361. $type,  
  362. $membership_id,  
  363. true 
  364. ); 
  365.  
  366. if ( ! empty( $fields ) ) { 
  367. lib3()->array->equip( 
  368. $fields,  
  369. 'enabled',  
  370. 'subject',  
  371. 'email_body',  
  372. 'period_unit',  
  373. 'period_type',  
  374. 'cc_enabled',  
  375. 'cc_email' 
  376. ); 
  377.  
  378. $comm->enabled = lib3()->is_true( $fields['enabled'] ); 
  379. $comm->subject = $fields['subject']; 
  380. $comm->message = $fields['email_body']; 
  381. $comm->period = array( 
  382. 'period_unit' => $fields['period_unit'],  
  383. 'period_type' => $fields['period_type'],  
  384. ); 
  385. $comm->cc_enabled = ! empty( $fields['cc_enabled'] ); 
  386. $comm->cc_email = $fields['cc_email']; 
  387.  
  388. $comm->save(); 
  389. $msg = MS_Helper_Settings::SETTINGS_MSG_UPDATED; 
  390.  
  391. return apply_filters( 
  392. 'ms_controller_communication_save',  
  393. $msg,  
  394. $type,  
  395. $fields,  
  396. $this 
  397. ); 
  398.  
  399. /** 
  400. * Prepare WordPress to add our custom TinyMCE button to the WYSIWYG editor. 
  401. * 
  402. * @since 1.0.1.0 
  403. * 
  404. * @see class-ms-view-settings-edit.php (function render_tab_messages_automated) 
  405. * @see ms-view-settings-automated-msg.js 
  406. */ 
  407. static public function add_mce_buttons() { 
  408. // Check user permissions. 
  409. if ( ! current_user_can( 'edit_posts' ) 
  410. && ! current_user_can( 'edit_pages' ) 
  411. ) { 
  412. return; 
  413.  
  414. // Check if WYSIWYG is enabled. 
  415. if ( 'true' != get_user_option( 'rich_editing' ) ) { 
  416. return; 
  417.  
  418. add_filter( 
  419. 'mce_external_plugins',  
  420. array( __CLASS__, 'add_variables_plugin' ) 
  421. ); 
  422. add_filter( 
  423. 'mce_buttons',  
  424. array( __CLASS__, 'register_variables_button' ) 
  425. ); 
  426.  
  427. /** 
  428. * Associate a javascript file with the new TinyMCE button. 
  429. * 
  430. * Hooks Filters: 
  431. * - mce_external_plugins 
  432. * 
  433. * @since 1.0.0 
  434. * 
  435. * @param array $plugin_array List of default TinyMCE plugin scripts. 
  436. * @return array Updated list of TinyMCE plugin scripts. 
  437. */ 
  438. public static function add_variables_plugin( $plugin_array ) { 
  439. $plugin_url = MS_Plugin::instance()->url; 
  440.  
  441. // This is a dummy reference (ms-admin.js is always loaded)! 
  442. // Actually this line would not be needed, but WordPress will not show 
  443. // our button when this is missing... 
  444. $plugin_array['ms_variable'] = $plugin_url . 'app/assets/js/ms-admin.js'; 
  445.  
  446. return $plugin_array; 
  447.  
  448. /** 
  449. * Register new "Insert variables" button in the editor. 
  450. * 
  451. * Hooks Filters: 
  452. * - mce_buttons 
  453. * 
  454. * @since 1.0.0 
  455. * 
  456. * @param array $buttons List of default TinyMCE buttons. 
  457. * @return array Updated list of TinyMCE buttons. 
  458. */ 
  459. public static function register_variables_button( $buttons ) { 
  460. array_push( $buttons, 'ms_variable' ); 
  461. return $buttons; 
  462.  
.