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

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