MS_Model_Communication

Communication model.

Defined (1)

The class is defined in the following location(s).

/app/model/class-ms-model-communication.php  
  1. class MS_Model_Communication extends MS_Model_CustomPostType { 
  2.  
  3. /** 
  4. * Model custom post type. 
  5. * Both static and class property are used to handle php 5.2 limitations. 
  6. * @since 1.0.0 
  7. * @var string $POST_TYPE 
  8. */ 
  9. protected static $POST_TYPE = 'ms_communication'; 
  10.  
  11. /** 
  12. * Holds a list of all Communication posts in the database. 
  13. * @since 1.0.1.0 
  14. * @var array $Communication_IDs 
  15. */ 
  16. protected static $Communication_IDs = array(); 
  17.  
  18. /** 
  19. * Communication types, static reference to loaded child objects. 
  20. * @since 1.0.0 
  21. * @var array $communications 
  22. */ 
  23. protected static $communications = array(); 
  24.  
  25. /** 
  26. * Communication type constants. 
  27. * @since 1.0.0 
  28. * @see $type 
  29. * @var string The communication type 
  30. */ 
  31. const COMM_TYPE_REGISTRATION = 'type_registration'; 
  32. const COMM_TYPE_REGISTRATION_FREE = 'type_registration_free'; 
  33. const COMM_TYPE_SIGNUP = 'type_signup'; 
  34. const COMM_TYPE_RESETPASSWORD = 'type_resetpassword'; 
  35. const COMM_TYPE_RENEWED = 'renewed'; 
  36. const COMM_TYPE_INVOICE = 'type_invoice'; 
  37. const COMM_TYPE_BEFORE_FINISHES = 'type_before_finishes'; 
  38. const COMM_TYPE_FINISHED = 'type_finished'; 
  39. const COMM_TYPE_AFTER_FINISHES = 'type_after_finishes'; 
  40. const COMM_TYPE_CANCELLED = 'type_cancelled'; 
  41. const COMM_TYPE_BEFORE_TRIAL_FINISHES = 'type_before_trial_finishes'; 
  42. const COMM_TYPE_INFO_UPDATE = 'type_info_update'; 
  43. const COMM_TYPE_CREDIT_CARD_EXPIRE = 'type_credit_card_expire'; 
  44. const COMM_TYPE_FAILED_PAYMENT = 'type_failed_payment'; 
  45. const COMM_TYPE_BEFORE_PAYMENT_DUE = 'type_before_payment_due'; 
  46. const COMM_TYPE_AFTER_PAYMENT_DUE = 'type_after_payment_due'; 
  47.  
  48. /** 
  49. * Communication variable constants. 
  50. * These variables are used inside emails and are replaced by variable value. 
  51. * @since 1.0.0 
  52. * @see comm_vars 
  53. * @var string The communication variable name. 
  54. */ 
  55. const COMM_VAR_MS_NAME = '%ms-name%'; 
  56. const COMM_VAR_MS_DESCRIPTION = '%ms-description%'; 
  57. const COMM_VAR_MS_INVOICE = '%ms-invoice%'; 
  58. const COMM_VAR_MS_ACCOUNT_PAGE_URL = '%ms-account-page-url%'; 
  59. const COMM_VAR_MS_REMAINING_DAYS = '%ms-remaining-days%'; 
  60. const COMM_VAR_MS_REMAINING_TRIAL_DAYS = '%ms-remaining-trial-days%'; 
  61. const COMM_VAR_MS_EXPIRY_DATE = '%ms-expiry-date%'; 
  62. const COMM_VAR_USER_DISPLAY_NAME = '%user-display-name%'; 
  63. const COMM_VAR_USER_FIRST_NAME = '%user-first-name%'; 
  64. const COMM_VAR_USER_LAST_NAME = '%user-last-name%'; 
  65. const COMM_VAR_USERNAME = '%username%'; 
  66. const COMM_VAR_PASSWORD = '%password%'; 
  67. const COMM_VAR_RESETURL = '%reset-url%'; 
  68. const COMM_VAR_BLOG_NAME = '%blog-name%'; 
  69. const COMM_VAR_BLOG_URL = '%blog-url%'; 
  70. const COMM_VAR_NET_NAME = '%network-name%'; 
  71. const COMM_VAR_NET_URL = '%network-url%'; 
  72.  
  73. /** 
  74. * Communication type. 
  75. * @since 1.0.0 
  76. * @var string The communication type. 
  77. */ 
  78. protected $type; 
  79.  
  80. /** 
  81. * Email subject. 
  82. * @since 1.0.0 
  83. * @var string The email subject. 
  84. */ 
  85. protected $subject; 
  86.  
  87. /** 
  88. * Email body message. 
  89. * @since 1.0.0 
  90. * @var string The email body message. 
  91. */ 
  92. protected $message; 
  93.  
  94. /** 
  95. * Communication period enabled. 
  96. * When the communication has a period to consider. 
  97. * @since 1.0.0 
  98. * @var bool The period enabled status. 
  99. */ 
  100. protected $period_enabled = false; 
  101.  
  102. /** 
  103. * The communication period settings. 
  104. * @since 1.0.0 
  105. * @var array 
  106. */ 
  107. protected $period = array( 
  108. 'period_unit' => 1,  
  109. 'period_type' => MS_Helper_Period::PERIOD_TYPE_DAYS,  
  110. ); 
  111.  
  112. /** 
  113. * Communication enabled status. 
  114. * @since 1.0.0 
  115. * @var string The communication enabled status. 
  116. */ 
  117. protected $enabled; 
  118.  
  119. /** 
  120. * Communication carbon copy enabled. 
  121. * @since 1.0.0 
  122. * @var string The communication carbon copy enabled status. 
  123. */ 
  124. protected $cc_enabled; 
  125.  
  126. /** 
  127. * Communication copied recipient email. 
  128. * @since 1.0.0 
  129. * @var string The copied recipient email. 
  130. */ 
  131. protected $cc_email; 
  132.  
  133. /** 
  134. * Defines a membership_id if this template overrides a default template. 
  135. * Default setting is 0, which indicates that the object is the default 
  136. * template of the specific type. 
  137. * @since 1.0.1.0 
  138. * @var int 
  139. */ 
  140. protected $membership_id = 0; 
  141.  
  142. /** 
  143. * Defines if a membership specific message should be used (true) or the 
  144. * default communication settings should be used (false). 
  145. * Only relevant when $membership_id is set. 
  146. * @since 1.0.1.0 
  147. * @var bool 
  148. */ 
  149. protected $override = false; 
  150.  
  151. /** 
  152. * Communication variables. 
  153. * @since 1.0.0 
  154. * @var string The communication vars. 
  155. */ 
  156. protected $comm_vars = array(); 
  157.  
  158. /** 
  159. * Communication queue of emails to send. 
  160. * @since 1.0.0 
  161. * @var string The communication queue. 
  162. */ 
  163. protected $queue = array(); 
  164.  
  165. /** 
  166. * Communication sent emails queue. 
  167. * Keep for a limited history of sent emails. 
  168. * @since 1.0.0 
  169. * @var string The communication sent queue. 
  170. */ 
  171. protected $sent_queue = array(); 
  172.  
  173. /** 
  174. * Communication default content type. 
  175. * @since 1.0.0 
  176. * @var string The communication default content type. 
  177. */ 
  178. protected $content_type = 'text/html'; 
  179.  
  180. /** 
  181. * Don't persist this fields. 
  182. * @since 1.0.0 
  183. * @var string[] The fields to ignore when persisting. 
  184. */ 
  185. static public $ignore_fields = array( 
  186. 'message',  
  187. 'name',  
  188. 'comm_vars',  
  189. ); 
  190.  
  191.  
  192. // 
  193. // 
  194. // 
  195. // -------------------------------------------------------------- COLLECTION 
  196.  
  197.  
  198. /** 
  199. * Returns the post-type of the current object. 
  200. * @since 1.0.0 
  201. * @return string The post-type name. 
  202. */ 
  203. public static function get_post_type() { 
  204. return parent::_post_type( self::$POST_TYPE ); 
  205.  
  206. /** 
  207. * Get custom register post type args for this model. 
  208. * @since 1.0.0 
  209. */ 
  210. public static function get_register_post_type_args() { 
  211. $args = array( 
  212. 'label' => __( 'Membership2 Email Templates', 'membership2' ),  
  213. ); 
  214.  
  215. return apply_filters( 
  216. 'ms_customposttype_register_args',  
  217. $args,  
  218. self::get_post_type() 
  219. ); 
  220.  
  221. /** 
  222. * Initializes the communications module. 
  223. * @since 1.0.1.0 
  224. */ 
  225. public static function init() { 
  226.  
  227. /** 
  228. * Get communication types. 
  229. * @since 1.0.0 
  230. * @return array The communication types. 
  231. */ 
  232. public static function get_communication_types() { 
  233. static $Types = null; 
  234.  
  235. if ( null === $Types ) { 
  236. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_AUTO_MSGS_PLUS ) ) { 
  237. $Types = array( 
  238. self::COMM_TYPE_REGISTRATION,  
  239. self::COMM_TYPE_REGISTRATION_FREE,  
  240. self::COMM_TYPE_SIGNUP,  
  241. self::COMM_TYPE_RESETPASSWORD,  
  242. self::COMM_TYPE_RENEWED,  
  243. self::COMM_TYPE_INVOICE,  
  244. self::COMM_TYPE_BEFORE_FINISHES,  
  245. self::COMM_TYPE_FINISHED,  
  246. self::COMM_TYPE_AFTER_FINISHES,  
  247. self::COMM_TYPE_CANCELLED,  
  248. self::COMM_TYPE_BEFORE_TRIAL_FINISHES,  
  249. self::COMM_TYPE_INFO_UPDATE,  
  250. self::COMM_TYPE_CREDIT_CARD_EXPIRE,  
  251. self::COMM_TYPE_FAILED_PAYMENT,  
  252. self::COMM_TYPE_BEFORE_PAYMENT_DUE,  
  253. self::COMM_TYPE_AFTER_PAYMENT_DUE,  
  254. ); 
  255. } else { 
  256. $Types = array( 
  257. self::COMM_TYPE_REGISTRATION,  
  258. self::COMM_TYPE_INVOICE,  
  259. self::COMM_TYPE_FINISHED,  
  260. self::COMM_TYPE_CANCELLED,  
  261. self::COMM_TYPE_INFO_UPDATE,  
  262. self::COMM_TYPE_CREDIT_CARD_EXPIRE,  
  263. self::COMM_TYPE_FAILED_PAYMENT,  
  264. ); 
  265.  
  266. return apply_filters( 
  267. 'ms_model_communication_get_communication_types',  
  268. $Types 
  269. ); 
  270.  
  271. /** 
  272. * Get Communication types and respective classes. 
  273. * @since 1.0.0 
  274. * @return array { 
  275. * Return array of $type => $class_name. 
  276. * @type string $type The communication type. 
  277. * @type string $class_name The class name of the communication type. 
  278. * } 
  279. */ 
  280. public static function get_communication_type_classes() { 
  281. static $type_classes; 
  282.  
  283. if ( empty( $type_classes ) ) { 
  284. $type_classes = array( 
  285. self::COMM_TYPE_REGISTRATION => 'MS_Model_Communication_Registration',  
  286. self::COMM_TYPE_REGISTRATION_FREE => 'MS_Model_Communication_Registration_Free',  
  287. self::COMM_TYPE_SIGNUP => 'MS_Model_Communication_Signup',  
  288. self::COMM_TYPE_RESETPASSWORD => 'MS_Model_Communication_Resetpass',  
  289. self::COMM_TYPE_RENEWED => 'MS_Model_Communication_Renewed',  
  290. self::COMM_TYPE_INVOICE => 'MS_Model_Communication_Invoice',  
  291. self::COMM_TYPE_BEFORE_FINISHES => 'MS_Model_Communication_Before_Finishes',  
  292. self::COMM_TYPE_FINISHED => 'MS_Model_Communication_Finished',  
  293. self::COMM_TYPE_AFTER_FINISHES => 'MS_Model_Communication_After_Finishes',  
  294. self::COMM_TYPE_CANCELLED => 'MS_Model_Communication_Cancelled',  
  295. self::COMM_TYPE_BEFORE_TRIAL_FINISHES => 'MS_Model_Communication_Before_Trial_Finishes',  
  296. self::COMM_TYPE_INFO_UPDATE => 'MS_Model_Communication_Info_Update',  
  297. self::COMM_TYPE_CREDIT_CARD_EXPIRE => 'MS_Model_Communication_Credit_Card_Expire',  
  298. self::COMM_TYPE_FAILED_PAYMENT => 'MS_Model_Communication_Failed_Payment',  
  299. self::COMM_TYPE_BEFORE_PAYMENT_DUE => 'MS_Model_Communication_Before_Payment_Due',  
  300. self::COMM_TYPE_AFTER_PAYMENT_DUE => 'MS_Model_Communication_After_Payment_Due',  
  301. ); 
  302.  
  303. return apply_filters( 
  304. 'ms_model_communication_get_communication_type_classes',  
  305. $type_classes 
  306. ); 
  307.  
  308. /** 
  309. * Get Communication types and respective titles. 
  310. * @since 1.0.0 
  311. * @param $membership Optional. If specified only Comm-Types relevant for 
  312. * that membership are returned. 
  313. * @return array { 
  314. * Return array of $type => $title. 
  315. * @type string $type The communication type. 
  316. * @type string $title The title of the communication type. 
  317. * } 
  318. */ 
  319. public static function get_communication_type_titles( $membership = null ) { 
  320. $type_titles = array( 
  321. self::COMM_TYPE_REGISTRATION => __( 'Signup - Completed with payment', 'membership2' ),  
  322. self::COMM_TYPE_REGISTRATION_FREE => __( 'Signup - Completed (free membership)', 'membership2' ),  
  323. self::COMM_TYPE_SIGNUP => __( 'Signup - User account created', 'membership2' ),  
  324. self::COMM_TYPE_RESETPASSWORD => __( 'Signup - Forgot Password', 'membership2' ),  
  325. self::COMM_TYPE_RENEWED => __( 'Subscription - Renewed', 'membership2' ),  
  326. self::COMM_TYPE_BEFORE_FINISHES => __( 'Subscription - Before expires', 'membership2' ),  
  327. self::COMM_TYPE_FINISHED => __( 'Subscription - Expired', 'membership2' ),  
  328. self::COMM_TYPE_AFTER_FINISHES => __( 'Subscription - After expired', 'membership2' ),  
  329. self::COMM_TYPE_CANCELLED => __( 'Subscription - Cancelled', 'membership2' ),  
  330. self::COMM_TYPE_BEFORE_TRIAL_FINISHES => __( 'Subscription - Trial finished', 'membership2' ),  
  331. self::COMM_TYPE_INFO_UPDATE => __( 'Payment - Profile updated', 'membership2' ),  
  332. self::COMM_TYPE_CREDIT_CARD_EXPIRE => __( 'Payment - Credit Card expires', 'membership2' ),  
  333. self::COMM_TYPE_INVOICE => __( 'Payment - Receipt/Invoice', 'membership2' ),  
  334. self::COMM_TYPE_FAILED_PAYMENT => __( 'Payment - Failed', 'membership2' ),  
  335. self::COMM_TYPE_BEFORE_PAYMENT_DUE => __( 'Payment - Before due', 'membership2' ),  
  336. self::COMM_TYPE_AFTER_PAYMENT_DUE => __( 'Payment - After due', 'membership2' ),  
  337. ); 
  338.  
  339. foreach ( $type_titles as $type => $title ) { 
  340. if ( ! self::is_valid_communication_type( $type ) ) { 
  341. unset( $type_titles[ $type ] ); 
  342.  
  343. if ( $membership && is_numeric( $membership ) ) { 
  344. $membership = MS_Factory::load( 'MS_Model_Membership', $membership ); 
  345.  
  346. if ( $membership instanceof MS_Model_Membership ) { 
  347. unset( $type_titles[ self::COMM_TYPE_SIGNUP ] ); 
  348. unset( $type_titles[ self::COMM_TYPE_RESETPASSWORD ] ); 
  349.  
  350. if ( ! $membership->has_trial() ) { 
  351. unset( $type_titles[ self::COMM_TYPE_BEFORE_TRIAL_FINISHES ] ); 
  352.  
  353. if ( $membership->is_free() ) { 
  354. unset( $type_titles[ self::COMM_TYPE_REGISTRATION ] ); 
  355. unset( $type_titles[ self::COMM_TYPE_INFO_UPDATE ] ); 
  356. unset( $type_titles[ self::COMM_TYPE_CREDIT_CARD_EXPIRE ] ); 
  357. unset( $type_titles[ self::COMM_TYPE_INVOICE ] ); 
  358. unset( $type_titles[ self::COMM_TYPE_FAILED_PAYMENT ] ); 
  359. unset( $type_titles[ self::COMM_TYPE_BEFORE_PAYMENT_DUE ] ); 
  360. unset( $type_titles[ self::COMM_TYPE_AFTER_PAYMENT_DUE ] ); 
  361. } else { 
  362. unset( $type_titles[ self::COMM_TYPE_REGISTRATION_FREE ] ); 
  363.  
  364. if ( MS_Model_Membership::PAYMENT_TYPE_PERMANENT == $membership->payment_type ) { 
  365. unset( $type_titles[ self::COMM_TYPE_BEFORE_FINISHES ] ); 
  366. unset( $type_titles[ self::COMM_TYPE_FINISHED ] ); 
  367. unset( $type_titles[ self::COMM_TYPE_AFTER_FINISHES ] ); 
  368.  
  369. return apply_filters( 
  370. 'ms_model_communication_get_communication_type_titles',  
  371. $type_titles 
  372. ); 
  373.  
  374. /** 
  375. * Validate communication type. 
  376. * @since 1.0.0 
  377. * @param string $type The type to validate. 
  378. * @return bool True if is valid. 
  379. */ 
  380. public static function is_valid_communication_type( $type ) { 
  381. $valid = ! empty( $type ) 
  382. && in_array( $type, self::get_communication_types() ); 
  383.  
  384. return apply_filters( 
  385. 'ms_model_communication_is_valid_communication_type',  
  386. $valid,  
  387. $type 
  388. ); 
  389.  
  390. /** 
  391. * Get count of all pending email messages. 
  392. * @since 1.0.1.0 
  393. * @return int 
  394. */ 
  395. static public function get_queue_count() { 
  396. $count = 0; 
  397. $memberships = self::get_communication_ids( null ); 
  398.  
  399. foreach ( $memberships as $ids ) { 
  400. foreach ( $ids as $id ) { 
  401. $comm = MS_Factory::load( 'MS_Model_Communication', $id ); 
  402. $count += count( $comm->queue ); 
  403.  
  404. return apply_filters( 
  405. 'ms_model_communication_get_queue_count',  
  406. $count,  
  407. $ids 
  408. ); 
  409.  
  410. /** 
  411. * Returns a list of communication IDs for the specified membership. 
  412. * Possible values: 
  413. * null .. All communication IDs are returned. 
  414. * 0 .. Global communication IDs are returned (defined in Settings page). 
  415. * <MembershipID> .. Communication IDs of that membership are returned. 
  416. * @since 1.0.1.0 
  417. * @param int $membership Indtifies a membership. 
  418. * @return array List of communication IDs. 
  419. */ 
  420. static protected function get_communication_ids( $membership ) { 
  421. if ( ! isset( self::$Communication_IDs[0] ) ) { 
  422. self::$Communication_IDs = array( 
  423. 0 => array(),  
  424. ); 
  425. $args = array( 
  426. 'post_type' => self::get_post_type(),  
  427. 'post_status' => 'any',  
  428. 'fields' => 'ids',  
  429. 'posts_per_page' => -1,  
  430. ); 
  431.  
  432. MS_Factory::select_blog(); 
  433. $query = new WP_Query( $args ); 
  434. $items = $query->posts; 
  435. MS_Factory::revert_blog(); 
  436.  
  437. foreach ( $items as $id ) { 
  438. $comm = MS_Factory::load( 'MS_Model_Communication', $id ); 
  439. self::$Communication_IDs[$comm->membership_id][$comm->type] = $id; 
  440.  
  441. if ( $membership instanceof MS_Model_Membership ) { 
  442. $key = $membership->id; 
  443. } else { 
  444. $key = $membership; 
  445.  
  446. if ( null === $key ) { 
  447. $result = self::$Communication_IDs; 
  448. } elseif ( isset( self::$Communication_IDs[$key] ) ) { 
  449. $result = self::$Communication_IDs[$key]; 
  450. } else { 
  451. $result = array(); 
  452.  
  453. return $result; 
  454.  
  455. /** 
  456. * Retrieve and return all communication types objects. 
  457. * @since 1.0.0 
  458. * @param MS_Model_Membership $membership Optional. If defined then we try 
  459. * to load overridden messages for that membership with fallback to 
  460. * the default messages. 
  461. * @return MS_Model_Communication[] The communication objects array. 
  462. */ 
  463. public static function get_communications( $membership = null ) { 
  464. $ids = self::get_communication_ids( $membership ); 
  465. $result = array(); 
  466.  
  467. if ( null === $membership ) { 
  468. // All comm items are requested. Index is counter. 
  469. foreach ( $ids as $sub_list ) { 
  470. foreach ( $sub_list as $type => $id ) { 
  471. $result[] = MS_Factory::load( 'MS_Model_Communication', $id ); 
  472. } else { 
  473. // A single membership is requested. Index is comm-type. 
  474. foreach ( $ids as $type => $id ) { 
  475. $result[$type] = MS_Factory::load( 'MS_Model_Communication', $id ); 
  476.  
  477. $types = self::get_communication_types(); 
  478. foreach ( $types as $type ) { 
  479. if ( ! isset( $result[$type] ) ) { 
  480. $result[$type] = self::get_communication( $type, $membership ); 
  481.  
  482. return apply_filters( 
  483. 'ms_model_communication_get_communications',  
  484. $result,  
  485. $membership 
  486. ); 
  487.  
  488. /** 
  489. * Get communication type object. 
  490. * Load from DB if exists, create a new one if not. 
  491. * @since 1.0.0 
  492. * @param string $type The type of the communication. 
  493. * @param MS_Model_Membership $membership Optional. If defined then we try 
  494. * to load the overridden template for that membership with fallback 
  495. * to the default template. 
  496. * @param bool $no_fallback Optional. Default value is false. 
  497. * True: Always return a communication for specified membership_id 
  498. * False: Fallback to default message if membership_id does not 
  499. * override the requested message. 
  500. * @return MS_Model_Communication The communication object. 
  501. */ 
  502. public static function get_communication( $type, $membership = null, $no_fallback = false ) { 
  503. $comm = null; 
  504. $key = 'all'; 
  505. $comm_id = 0; 
  506.  
  507. /** 
  508. * If the Membership specific communication is not defined or it 
  509. * is configured to use the default communication then fetch the 
  510. * default communication object! 
  511. */ 
  512. $can_fallback = $membership && ! $no_fallback; 
  513.  
  514. if ( self::is_valid_communication_type( $type ) ) { 
  515. $membership_id = 0; 
  516.  
  517. if ( $membership ) { 
  518. if ( $membership instanceof MS_Model_Membership ) { 
  519. $membership_id = $membership->id; 
  520. } elseif ( is_scalar( $membership ) ) { 
  521. $membership_id = $membership; 
  522. if ( $membership_id ) { 
  523. $key = $membership_id; 
  524.  
  525. if ( empty( self::$Communication_IDs[ $key ] ) ) { 
  526. self::$Communication_IDs[ $key ] = array(); 
  527.  
  528. if ( ! empty( self::$Communication_IDs[ $key ][ $type ] ) ) { 
  529. $comm_id = self::$Communication_IDs[ $key ][ $type ]; 
  530. } else { 
  531. $args = array( 
  532. 'post_type' => self::get_post_type(),  
  533. 'post_status' => 'any',  
  534. 'fields' => 'ids',  
  535. 'posts_per_page' => 1,  
  536. 'post_parent' => $membership_id,  
  537. 'meta_query' => array( 
  538. array( 
  539. 'key' => 'type',  
  540. 'value' => $type,  
  541. 'compare' => '=',  
  542. ),  
  543. ); 
  544.  
  545. $args = apply_filters( 
  546. 'ms_model_communication_get_communications_args',  
  547. $args 
  548. ); 
  549.  
  550. MS_Factory::select_blog(); 
  551. $query = new WP_Query( $args ); 
  552. $items = $query->posts; 
  553. MS_Factory::revert_blog(); 
  554.  
  555. if ( 1 == count( $items ) ) { 
  556. $comm_id = $items[0]; 
  557.  
  558. $comm_classes = self::get_communication_type_classes(); 
  559. $comm_class = $comm_classes[ $type ]; 
  560. if ( $comm_id ) { 
  561. $comm = MS_Factory::load( $comm_class, $comm_id ); 
  562. } elseif ( ! $can_fallback ) { 
  563. $comm = MS_Factory::create( $comm_class ); 
  564. $comm->reset_to_default(); 
  565. $comm->membership_id = $membership_id; 
  566.  
  567. if ( $comm ) { 
  568. self::$Communication_IDs[$comm->membership_id][$type] = $comm->id; 
  569.  
  570. // If no template found or defined then fallback to default template. 
  571. $should_fallback = ! $comm || ! $comm->override; 
  572. if ( $can_fallback && $should_fallback ) { 
  573. $comm = self::get_communication( $type, null ); 
  574.  
  575. return apply_filters( 
  576. 'ms_model_communication_get_communication_' . $type,  
  577. $comm,  
  578. $membership,  
  579. $no_fallback 
  580. ); 
  581.  
  582.  
  583. // 
  584. // 
  585. // 
  586. // ------------------------------------------------------------- SINGLE ITEM 
  587.  
  588.  
  589. /** 
  590. * Communication constructor. 
  591. * @since 1.0.0 
  592. */ 
  593. public function __construct() { 
  594. $this->comm_vars = array( 
  595. self::COMM_VAR_MS_NAME => __( 'Subscription: Membership Name', 'membership2' ),  
  596. self::COMM_VAR_MS_DESCRIPTION => __( 'Subscription: Membership Description', 'membership2' ),  
  597. self::COMM_VAR_MS_REMAINING_DAYS => __( 'Subscription: Remaining days', 'membership2' ),  
  598. self::COMM_VAR_MS_REMAINING_TRIAL_DAYS => __( 'Subscription: Remaining trial days', 'membership2' ),  
  599. self::COMM_VAR_MS_EXPIRY_DATE => __( 'Subscription: Expiration date', 'membership2' ),  
  600. self::COMM_VAR_MS_INVOICE => __( 'Subscription: Current Invoice', 'membership2' ),  
  601. self::COMM_VAR_USER_DISPLAY_NAME => __( 'User: Display name', 'membership2' ),  
  602. self::COMM_VAR_USER_FIRST_NAME => __( 'User: First name', 'membership2' ),  
  603. self::COMM_VAR_USER_LAST_NAME => __( 'User: Last name', 'membership2' ),  
  604. self::COMM_VAR_USERNAME => __( 'User: Login name', 'membership2' ),  
  605. self::COMM_VAR_PASSWORD => __( 'User: Password', 'membership2' ),  
  606. self::COMM_VAR_RESETURL => __( 'User: Reset Password URL', 'membership2' ),  
  607. self::COMM_VAR_MS_ACCOUNT_PAGE_URL => __( 'Site: User Account URL', 'membership2' ),  
  608. self::COMM_VAR_BLOG_NAME => __( 'Site: Name', 'membership2' ),  
  609. self::COMM_VAR_BLOG_URL => __( 'Site: URL', 'membership2' ),  
  610. ); 
  611.  
  612. $has_membership = true; 
  613. if ( self::COMM_TYPE_SIGNUP == $this->type ) { 
  614. $has_membership = false; 
  615. } else { 
  616. // Password is only available in the Signup email. 
  617. unset( $this->comm_vars[self::COMM_VAR_PASSWORD] ); 
  618.  
  619. if ( self::COMM_TYPE_RESETPASSWORD == $this->type ) { 
  620. $has_membership = false; 
  621. } else { 
  622. // Reset-Key is only available in the Forgot Password email. 
  623. unset( $this->comm_vars[self::COMM_VAR_RESETURL] ); 
  624.  
  625. if ( ! $has_membership ) { 
  626. // If no membership context is available then remove those variables. 
  627. unset( $this->comm_vars[self::COMM_VAR_MS_NAME] ); 
  628. unset( $this->comm_vars[self::COMM_VAR_MS_DESCRIPTION] ); 
  629. unset( $this->comm_vars[self::COMM_VAR_MS_REMAINING_DAYS] ); 
  630. unset( $this->comm_vars[self::COMM_VAR_MS_REMAINING_TRIAL_DAYS] ); 
  631. unset( $this->comm_vars[self::COMM_VAR_MS_EXPIRY_DATE] ); 
  632. unset( $this->comm_vars[self::COMM_VAR_MS_INVOICE] ); 
  633.  
  634. if ( is_multisite() ) { 
  635. $this->comm_vars[self::COMM_VAR_NET_NAME] = __( 'Network: Name', 'membership2' ); 
  636. $this->comm_vars[self::COMM_VAR_NET_URL] = __( 'Network: URL', 'membership2' ); 
  637.  
  638. /** 
  639. * Save the current communication item. 
  640. * This function allows us easier debugging of communication issues. 
  641. * @since 1.0.1.1 
  642. */ 
  643. public function save() { 
  644. parent::save(); 
  645.  
  646. /** 
  647. * Customize the data that is written to the DB. 
  648. * @since 1.0.1.0 
  649. */ 
  650. public function save_post_data( $post ) { 
  651. $post['post_content'] = $this->message; 
  652. $post['post_excerpt'] = $this->message; 
  653. $post['post_parent'] = intval( $this->membership_id ); 
  654. return $post; 
  655.  
  656. /** 
  657. * Hook process communication actions. 
  658. * @since 1.0.1.0 
  659. */ 
  660. public function load_post_data( $post ) { 
  661. $this->message = $post->post_content; 
  662. $this->membership_id = intval( $post->post_parent ); 
  663.  
  664. /** 
  665. * Communication default communication. 
  666. * To be overridden by children classes creating a new object with the default subject, message, enabled, etc. 
  667. * @since 1.0.0 
  668. */ 
  669. public function reset_to_default() { 
  670. do_action( 
  671. 'ms_model_communication_reset_to_default',  
  672. $this->type,  
  673. $this 
  674. ); 
  675.  
  676. /** 
  677. * Returns the title of the communication object. 
  678. * @since 1.0.1.0 
  679. * @return string 
  680. */ 
  681. public function get_title() { 
  682. $result = ''; 
  683. $titles = self::get_communication_type_titles(); 
  684.  
  685. if ( isset( $titles[ $this->type ] ) ) { 
  686. $result = $titles[ $this->type ]; 
  687.  
  688. return apply_filters( 
  689. 'ms_model_communication_get_title',  
  690. $result 
  691. ); 
  692.  
  693. /** 
  694. * Get communication description. 
  695. * Override it in children classes. 
  696. * @since 1.0.0 
  697. * @return string The description. 
  698. */ 
  699. public function get_description() { 
  700. $description = __( 'Override this description in child class', 'membership2' ); 
  701.  
  702. return apply_filters( 
  703. 'ms_model_communication_get_description',  
  704. $description 
  705. ); 
  706.  
  707. /** 
  708. * Populates the field title/description of the Period before/after field 
  709. * in the admin settings. 
  710. * Override this in child classes to customize the label. 
  711. * @since 1.0.0 
  712. * @param array $field A HTML definition, passed to lib3()->html->element() 
  713. */ 
  714. public function set_period_name( $field ) { 
  715. $field['title'] = __( 'Period before/after', 'membership2' ); 
  716.  
  717. return $field; 
  718.  
  719. /** 
  720. * Process communication. 
  721. * Send email and manage queue. 
  722. * @since 1.0.0 
  723. * @internal Called by MS_Controller_Communication::process_queue() 
  724. */ 
  725. public function process_queue() { 
  726. do_action( 
  727. 'ms_model_communication_process_queue_before',  
  728. $this 
  729. ); 
  730.  
  731. /** 
  732. * Use `define( 'MS_STOP_EMAILS', true );` in wp-config.php to prevent 
  733. * Membership2 from sending *any* emails to users. 
  734. * Also any currently enqueued message is removed from the queue 
  735. * @since 1.0.0 
  736. */ 
  737. if ( MS_Plugin::get_modifier( 'MS_STOP_EMAILS' ) ) { 
  738. $this->queue = array(); 
  739.  
  740. if ( $this->enabled && ! $this->check_object_lock() && count( $this->queue ) ) { 
  741. $this->set_object_lock(); 
  742.  
  743. // Max emails that are sent in one process call. 
  744. $max_emails_qty = apply_filters( 
  745. 'ms_model_communication_process_queue_max_email_qty',  
  746. 50 
  747. ); 
  748. $count = 0; 
  749.  
  750. // Email-processing timeout, in seconds. 
  751. $time_limit = apply_filters( 
  752. 'ms_model_communication_process_queue_time_limit',  
  753. 10 
  754. ); 
  755. $start_time = time(); 
  756.  
  757. foreach ( $this->queue as $subscription_id => $timestamp ) { 
  758. // Remove invalid subscription items from queue. 
  759. if ( ! $subscription_id || ! is_numeric( $subscription_id ) ) { 
  760. unset( $this->queue[ $subscription_id ] ); 
  761. continue; 
  762.  
  763. if ( time() > $start_time + $time_limit 
  764. || ++$count > $max_emails_qty 
  765. ) { 
  766. break; 
  767.  
  768. $subscription = MS_Factory::load( 
  769. 'MS_Model_Relationship',  
  770. $subscription_id 
  771. ); 
  772.  
  773. $this->remove_from_queue( $subscription_id ); 
  774. $was_sent = $this->send_message( $subscription ); 
  775.  
  776. if ( ! $was_sent ) { 
  777. do_action( 
  778. 'lib2_debug_log',  
  779. sprintf( 
  780. '[error: Communication email failed] comm_type=%s, subscription_id=%s, user_id=%s',  
  781. $this->type,  
  782. $subscription->id,  
  783. $subscription->user_id 
  784. ); 
  785.  
  786. $this->save(); 
  787. $this->delete_object_lock(); 
  788.  
  789. do_action( 'ms_model_communication_process_queue_after', $this ); 
  790.  
  791. /** 
  792. * Enqueue a message in the "send queue". 
  793. * Action handler hooked up in child classes. 
  794. * @since 1.0.0 
  795. * @api 
  796. * @param MS_Model_Event $event The event object. 
  797. * @param MS_Model_Relationship $subscription The subscription to send message to. 
  798. */ 
  799. public function enqueue_messages( $event, $subscription ) { 
  800. do_action( 'ms_model_communication_enqueue_messages_before', $this ); 
  801.  
  802. if ( $this->enabled ) { 
  803. $this->add_to_queue( $subscription->id ); 
  804. $this->save(); 
  805.  
  806. do_action( 'ms_model_communication_enqueue_messages_after', $this ); 
  807.  
  808. /** 
  809. * Process a communication event. 
  810. * This is used to execute custom code before or instead of simply enqueuing 
  811. * the communication. 
  812. * Common usage: 
  813. * - Instantly send the message via $this->send_message() 
  814. * - Only enqueue message for specific $subscriptions (e.g. free ones) 
  815. * @since 1.0.1.0 
  816. * @param MS_Model_Event $event 
  817. * @param MS_Model_Relationship $subscription 
  818. */ 
  819. public function process_communication( $event, $subscription ) { 
  820. // Can be overwritten in the child class for custom actions. 
  821.  
  822. /** 
  823. * Add a message in the "send queue". 
  824. * @since 1.0.0 
  825. * @api 
  826. * @param int $subscription_id The membership relationship ID to add to queue. 
  827. */ 
  828. public function add_to_queue( $subscription_id ) { 
  829. do_action( 'ms_model_communication_add_to_queue_before', $this ); 
  830.  
  831. /** 
  832. * Documented in process_queue() 
  833. * @since 1.0.0 
  834. */ 
  835. if ( MS_Plugin::get_modifier( 'MS_STOP_EMAILS' ) ) { 
  836. $subscription = MS_Factory::load( 'MS_Model_Relationship', $subscription_id ); 
  837. do_action( 
  838. 'lib2_debug_log',  
  839. sprintf( 
  840. 'Following Email was not sent: "%s" to user "%s".',  
  841. $this->type,  
  842. $subscription->user_id 
  843. ); 
  844.  
  845. return false; 
  846.  
  847. $is_enqueued = array_key_exists( $subscription_id, $this->queue ); 
  848.  
  849. if ( $this->enabled && ! $is_enqueued ) { 
  850. $can_add = true; 
  851.  
  852. /** 
  853. * Check if email enqueuing is limited to prevent duplicate emails. 
  854. * Use setting `define( 'MS_DUPLICATE_EMAIL_HOURS', 24 )` to prevent 
  855. * duplicate emails from being sent for 24 hours. 
  856. * @var int Number of hours 
  857. */ 
  858. $pause_hours = 0; 
  859. if ( defined( 'MS_DUPLICATE_EMAIL_HOURS' ) && is_numeric( MS_DUPLICATE_EMAIL_HOURS ) ) { 
  860. $pause_hours = MS_DUPLICATE_EMAIL_HOURS; 
  861. if ( $pause_hours > 0 ) { 
  862. if ( array_key_exists( $subscription_id, $this->sent_queue ) ) { 
  863. $pause_hours = apply_filters( 
  864. 'ms_model_communication_hours_before_resend',  
  865. $pause_hours 
  866. ); 
  867.  
  868. /** 
  869. * The sent_queue is saved in DB and only contains messages 
  870. * from the current Communications object. So 
  871. * $subscription_id defines the email contents and receiver. 
  872. */ 
  873. $sent_date = $this->sent_queue[ $subscription_id ]; 
  874. $now = MS_Helper_Period::current_time(); 
  875.  
  876. $current_delay = MS_Helper_Period::subtract_dates( 
  877. $now,  
  878. $sent_date,  
  879. HOURS_IN_SECONDS 
  880. ); 
  881.  
  882. $can_add = $current_delay >= $pause_hours; 
  883.  
  884. if ( $can_add ) { 
  885. $this->queue[ $subscription_id ] = MS_Helper_Period::current_time(); 
  886.  
  887. do_action( 'ms_model_communication_add_to_queue_after', $this ); 
  888.  
  889. /** 
  890. * Remove from queue. 
  891. * Delete history of sent messages after max is reached. 
  892. * @since 1.0.0 
  893. * @param int $subscription_id The membership relationship ID to remove from queue. 
  894. */ 
  895. public function remove_from_queue( $subscription_id ) { 
  896. do_action( 'ms_model_communication_remove_from_queue_before', $this ); 
  897.  
  898. // Delete history 
  899. if ( count( $this->sent_queue ) > $max_history ) { 
  900. $this->sent_queue = array_slice( 
  901. $this->sent_queue,  
  902. -100,  
  903. $max_history,  
  904. true 
  905. ); 
  906.  
  907. $this->sent_queue[ $subscription_id ] = MS_Helper_Period::current_time(); 
  908. unset( $this->queue[ $subscription_id ] ); 
  909.  
  910. $max_history = apply_filters( 
  911. 'ms_model_communication_sent_queue_max_history',  
  912. 200 
  913. ); 
  914.  
  915. do_action( 'ms_model_communication_remove_from_queue_after', $this ); 
  916.  
  917. /** 
  918. * Send email message. 
  919. * Delete history of sent messages after max is reached. 
  920. * @since 1.0.0 
  921. * @param mixed $reference A reference to identify the member/subscription. 
  922. * @return bool True if successfully sent email. 
  923. */ 
  924. public function send_message( $reference ) { 
  925. $user_id = 0; 
  926. $subscription = null; 
  927. $member = null; 
  928.  
  929. if ( $reference instanceof MS_Model_Relationship ) { 
  930. $user_id = $reference->user_id; 
  931. $subscription = $reference; 
  932. $member = $subscription->get_member(); 
  933. } elseif ( $reference instanceof MS_Model_Member ) { 
  934. $user_id = $reference->id; 
  935. $member = $reference; 
  936. $subscription = null; 
  937.  
  938. /** 
  939. * Documented in process_queue() 
  940. * @since 1.0.1.0 
  941. */ 
  942. if ( MS_Plugin::get_modifier( 'MS_STOP_EMAILS' ) ) { 
  943. do_action( 
  944. 'lib2_debug_log',  
  945. sprintf( 
  946. 'Following Email was not sent: "%s" to user "%s".',  
  947. $this->type,  
  948. $user_id 
  949. ); 
  950.  
  951. return false; 
  952.  
  953. do_action( 
  954. 'ms_model_communication_send_message_before',  
  955. $member,  
  956. $subscription,  
  957. $this 
  958. ); 
  959.  
  960. $sent = false; 
  961.  
  962. if ( $this->enabled ) { 
  963. if ( ! is_email( $member->email ) ) { 
  964. do_action( 
  965. 'lib2_debug_log',  
  966. sprintf( 
  967. 'Invalid user email. User_id: %1$s, email: %2$s',  
  968. $user_id,  
  969. $member->email 
  970. ); 
  971. return false; 
  972.  
  973. $comm_vars = $this->get_comm_vars( $subscription, $member ); 
  974.  
  975. // Replace the email variables. 
  976. $message = str_replace( 
  977. array_keys( $comm_vars ),  
  978. array_values( $comm_vars ),  
  979. stripslashes( $this->message ) 
  980. ); 
  981.  
  982. $subject = str_replace( 
  983. array_keys( $comm_vars ),  
  984. array_values( $comm_vars ),  
  985. stripslashes( $this->subject ) 
  986. ); 
  987.  
  988. $html_message = wpautop( $message ); 
  989. $text_message = strip_tags( 
  990. preg_replace( 
  991. '/\<a .*?href="(.*?)".*?\>.*?\<\/a\>/is',  
  992. '$0 [$1]',  
  993. $message 
  994. ); 
  995. $subject = strip_tags( 
  996. preg_replace( 
  997. '/\<a .*?href="(.*?)".*?\>.*?\<\/a\>/is',  
  998. '$0 [$1]',  
  999. $subject 
  1000. ); 
  1001.  
  1002. $message = $text_message; 
  1003.  
  1004. if ( 'text/html' == $this->get_mail_content_type() ) { 
  1005. $this->add_filter( 
  1006. 'wp_mail_content_type',  
  1007. 'get_mail_content_type' 
  1008. ); 
  1009. $message = $html_message; 
  1010.  
  1011. $recipients = array( $member->email ); 
  1012. if ( $this->cc_enabled ) { 
  1013. $recipients[] = $this->cc_email; 
  1014.  
  1015. $admin_emails = MS_Model_Member::get_admin_user_emails(); 
  1016. $headers = ''; 
  1017.  
  1018. if ( ! empty( $admin_emails[0] ) ) { 
  1019. $headers = array( 
  1020. sprintf( 
  1021. 'From: %s <%s> ',  
  1022. get_option( 'blogname' ),  
  1023. $admin_emails[0] 
  1024. ); 
  1025.  
  1026. $recipients = apply_filters( 
  1027. 'ms_model_communication_send_message_recipients',  
  1028. $recipients,  
  1029. $this,  
  1030. $subscription 
  1031. ); 
  1032. $html_message = apply_filters( 
  1033. 'ms_model_communication_send_message_html_message',  
  1034. $html_message,  
  1035. $this,  
  1036. $subscription 
  1037. ); 
  1038. $text_message = apply_filters( 
  1039. 'ms_model_communication_send_message_text_message',  
  1040. $text_message,  
  1041. $this,  
  1042. $subscription 
  1043. ); 
  1044. $subject = apply_filters( 
  1045. 'ms_model_communication_send_message_subject',  
  1046. $subject,  
  1047. $this,  
  1048. $subscription 
  1049. ); 
  1050. $headers = apply_filters( 
  1051. 'ms_model_communication_send_message_headers',  
  1052. $headers,  
  1053. $this,  
  1054. $subscription 
  1055. ); 
  1056.  
  1057. /** 
  1058. * Send the mail. 
  1059. * wp_mail will not throw an error, so no error-suppression/handling 
  1060. * is required here. On error the function response is FALSE. 
  1061. */ 
  1062. $sent = wp_mail( $recipients, $subject, $message, $headers ); 
  1063.  
  1064. // Log the outgoing email. 
  1065. do_action( 
  1066. 'lib2_debug_log',  
  1067. sprintf( 
  1068. 'Sent email [%s] to <%s>: %s',  
  1069. $this->type,  
  1070. implode( '>, <', $recipients ),  
  1071. $sent ? 'OK' : 'ERR' 
  1072. ); 
  1073.  
  1074. if ( 'text/html' == $this->get_mail_content_type() ) { 
  1075. $this->remove_filter( 
  1076. 'wp_mail_content_type',  
  1077. 'get_mail_content_type' 
  1078. ); 
  1079.  
  1080. do_action( 
  1081. 'ms_model_communication_send_message',  
  1082. $member,  
  1083. $subscription,  
  1084. $this 
  1085. ); 
  1086.  
  1087. return $sent; 
  1088.  
  1089. /** 
  1090. * Replace comm_vars with corresponding values. 
  1091. * @since 1.0.0 
  1092. * @param MS_Model_Relationship $subscription The membership relationship to send message to. 
  1093. * @param MS_Model_Member $member The member object to get info from. 
  1094. * @return array { 
  1095. * Returns array of ( $var_name => $var_replace ). 
  1096. * @type string $var_name The variable name to replace. 
  1097. * @type string $var_replace The variable corresponding replace string. 
  1098. * } 
  1099. */ 
  1100. public function get_comm_vars( $subscription, $member ) { 
  1101. $currency = MS_Plugin::instance()->settings->currency . ' '; 
  1102. $invoice = null; 
  1103. $membership = null; 
  1104.  
  1105. if ( $subscription && $subscription instanceof MS_Model_Relationship ) { 
  1106. // First try to fetch the current invoice. 
  1107. $invoice = $subscription->get_current_invoice( false ); 
  1108. $prev_invoice = $subscription->get_previous_invoice(); 
  1109.  
  1110. // If no current invoice exists then fetch the previous invoice. 
  1111. if ( empty( $invoice ) ) { 
  1112. $invoice = $prev_invoice; 
  1113.  
  1114. $membership = $subscription->get_membership(); 
  1115.  
  1116. $comm_vars = apply_filters( 
  1117. 'ms_model_communication_comm_vars',  
  1118. $this->comm_vars,  
  1119. $this->type,  
  1120. $member,  
  1121. $subscription 
  1122. ); 
  1123.  
  1124. $wp_user = $member->get_user(); 
  1125.  
  1126. foreach ( $comm_vars as $key => $description ) { 
  1127. $var_value = ''; 
  1128.  
  1129. switch ( $key ) { 
  1130. case self::COMM_VAR_BLOG_NAME: 
  1131. $var_value = get_option( 'blogname' ); 
  1132. break; 
  1133.  
  1134. case self::COMM_VAR_BLOG_URL: 
  1135. $var_value = get_option( 'home' ); 
  1136. break; 
  1137.  
  1138. case self::COMM_VAR_USERNAME: 
  1139. $var_value = $member->username; 
  1140. break; 
  1141.  
  1142. case self::COMM_VAR_PASSWORD: 
  1143. /** 
  1144. * $member->password is ONLY available in the same request 
  1145. * when the new user account was created! After this we only 
  1146. * have the encrypted password in the DB, and the plain-text 
  1147. * version will never be available again in code... 
  1148. * @since 1.0.1.1 
  1149. */ 
  1150. if ( self::COMM_TYPE_SIGNUP == $this->type ) { 
  1151. $var_value = $member->password; 
  1152. break; 
  1153.  
  1154. case self::COMM_VAR_RESETURL: 
  1155. /** 
  1156. * The reset-URL is only available in the password reset 
  1157. * email template. Reason is, that only ONE valid URL can 
  1158. * exist at a time, so if every email would contain a 
  1159. * reset URL it would invalidate all previous reset URLs. 
  1160. * @since 1.0.2.3 
  1161. */ 
  1162. if ( self::COMM_TYPE_RESETPASSWORD == $this->type ) { 
  1163. $reset = $member->new_password_reset_key(); 
  1164. $var_value = $reset->url; 
  1165. break; 
  1166.  
  1167. case self::COMM_VAR_USER_DISPLAY_NAME: 
  1168. $var_value = $wp_user->display_name; 
  1169. break; 
  1170.  
  1171. case self::COMM_VAR_USER_FIRST_NAME: 
  1172. $var_value = $member->first_name; 
  1173. break; 
  1174.  
  1175. case self::COMM_VAR_USER_LAST_NAME: 
  1176. $var_value = $member->last_name; 
  1177. break; 
  1178.  
  1179. case self::COMM_VAR_NET_NAME: 
  1180. $var_value = get_site_option( 'site_name' ); 
  1181. break; 
  1182.  
  1183. case self::COMM_VAR_NET_URL: 
  1184. $var_value = get_site_option( 'siteurl' ); 
  1185. break; 
  1186.  
  1187. case self::COMM_VAR_MS_ACCOUNT_PAGE_URL: 
  1188. $var_value = sprintf( 
  1189. '<a href="%s">%s</a>',  
  1190. MS_Model_Pages::get_page_url( MS_Model_Pages::MS_PAGE_ACCOUNT ),  
  1191. __( 'account page', 'membership2' ) 
  1192. ); 
  1193. break; 
  1194.  
  1195. // Needs: $membership 
  1196. case self::COMM_VAR_MS_NAME: 
  1197. if ( $membership && $membership->name ) { 
  1198. $var_value = $membership->name; 
  1199. break; 
  1200.  
  1201. // Needs: $membership 
  1202. case self::COMM_VAR_MS_DESCRIPTION: 
  1203. if ( $membership && $membership->description ) { 
  1204. $var_value = $membership->get_description(); 
  1205. break; 
  1206.  
  1207. // Needs: $invoice 
  1208. case self::COMM_VAR_MS_INVOICE: 
  1209. if ( $invoice ) { 
  1210. if ( $invoice->total > 0 || $invoice->uses_trial ) { 
  1211. $attr = array( 
  1212. 'post_id' => $invoice->id,  
  1213. 'pay_button' => 0,  
  1214. ); 
  1215. $scode = MS_Factory::load( 'MS_Controller_Shortcode' ); 
  1216. $var_value = $scode->membership_invoice( $attr ); 
  1217. break; 
  1218.  
  1219. // Needs: $subscription 
  1220. case self::COMM_VAR_MS_REMAINING_DAYS: 
  1221. if ( $subscription ) { 
  1222. $days = $subscription->get_remaining_period(); 
  1223. $var_value = sprintf( 
  1224. __( '%s day%s', 'membership2' ),  
  1225. $days,  
  1226. abs( $days ) > 1 ? 's': '' 
  1227. ); 
  1228. break; 
  1229.  
  1230. // Needs: $subscription 
  1231. case self::COMM_VAR_MS_REMAINING_TRIAL_DAYS: 
  1232. if ( $subscription ) { 
  1233. $days = $subscription->get_remaining_trial_period(); 
  1234. $var_value = sprintf( 
  1235. __( '%s day%s', 'membership2' ),  
  1236. $days,  
  1237. abs( $days ) > 1 ? 's': '' 
  1238. ); 
  1239. break; 
  1240.  
  1241. // Needs: $subscription 
  1242. case self::COMM_VAR_MS_EXPIRY_DATE: 
  1243. if ( $subscription ) { 
  1244. $var_value = $subscription->expire_date; 
  1245. break; 
  1246.  
  1247. $comm_vars[ $key ] = apply_filters( 
  1248. 'ms_model_communication_send_message_comm_var-' . $key,  
  1249. $var_value,  
  1250. $this->type,  
  1251. $member,  
  1252. $subscription,  
  1253. $invoice 
  1254. ); 
  1255.  
  1256. return apply_filters( 
  1257. 'ms_model_communication_get_comm_vars',  
  1258. $comm_vars,  
  1259. $member 
  1260. ); 
  1261.  
  1262. /** 
  1263. * Get Email content type. 
  1264. * Eg. text/html, text. 
  1265. * @since 1.0.0 
  1266. * @return string 
  1267. */ 
  1268. public function get_mail_content_type() { 
  1269. $this->content_type = apply_filters( 
  1270. 'ms_model_communication_set_html_content_type',  
  1271. 'text/html' 
  1272. ); 
  1273.  
  1274. return $this->content_type; 
  1275.  
  1276. /** 
  1277. * Validate specific property before set. 
  1278. * @since 1.0.0 
  1279. * @param string $name The name of a property to associate. 
  1280. * @param mixed $value The value of a property. 
  1281. */ 
  1282. public function __set( $property, $value ) { 
  1283. switch ( $property ) { 
  1284. case 'type': 
  1285. if ( $this->is_valid_communication_type( $value ) ) { 
  1286. $this->$property = $value; 
  1287. break; 
  1288.  
  1289. case 'subject': 
  1290. $this->$property = sanitize_text_field( $value ); 
  1291. break; 
  1292.  
  1293. case 'cc_email': 
  1294. if ( is_email( $value ) ) { 
  1295. $this->$property = $value; 
  1296. break; 
  1297.  
  1298. case 'enabled': 
  1299. case 'cc_enabled': 
  1300. case 'override': 
  1301. $this->$property = lib3()->is_true( $value ); 
  1302. break; 
  1303.  
  1304. case 'period': 
  1305. $this->$property = $this->validate_period( $value ); 
  1306. break; 
  1307.  
  1308. case 'period_unit': 
  1309. $this->period['period_unit'] = $this->validate_period_unit( $value ); 
  1310. break; 
  1311.  
  1312. case 'period_type': 
  1313. $this->period['period_type'] = $this->validate_period_type( $value ); 
  1314. break; 
  1315.  
  1316. default: 
  1317. if ( property_exists( $this, $property ) ) { 
  1318. $this->$property = $value; 
  1319. break; 
  1320.  
  1321. do_action( 
  1322. 'ms_model_communication__set_after',  
  1323. $property,  
  1324. $value,  
  1325. $this 
  1326. ); 
  1327.  
  1328. };