Advertisement
Guest User

check_membership_status

a guest
Dec 1st, 2015
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.31 KB | None | 0 0
  1. /**
  2. * Check membership status.
  3. *
  4. * Execute actions when time/period condition are met.
  5. * E.g. change membership status, add communication to queue, create invoices.
  6. *
  7. * This check is called via a cron job.
  8. *
  9. * @since 1.0.0
  10. * @internal Used by Cron
  11. * @see MS_Model_Plugin::check_membership_status()
  12. */
  13. public function check_membership_status() {
  14. do_action(
  15. 'ms_model_relationship_check_membership_status_before',
  16. $this
  17. );
  18.  
  19. /**
  20. * Use `define( 'MS_LOCK_SUBSCRIPTIONS', true );` in wp-config.php to prevent
  21. * Membership2 from sending *any* emails to users.
  22. * Also any currently enqueued message is removed from the queue
  23. *
  24. * @since 1.0.0
  25. */
  26. if ( MS_Plugin::get_modifier( 'MS_LOCK_SUBSCRIPTIONS' ) ) {
  27. return false;
  28. }
  29.  
  30. $membership = $this->get_membership();
  31. $remaining_days = $this->get_remaining_period();
  32. $remaining_trial_days = $this->get_remaining_trial_period();
  33.  
  34. $comms = MS_Model_Communication::get_communications( $membership );
  35. $invoice_before_days = 5;//@todo create a setting to configure this period.
  36. $deactivate_expired_after_days = 30; //@todo create a setting to configure this period.
  37. $deactivate_pending_after_days = 30; //@todo create a setting to configure this period.
  38. $deactivate_trial_expired_after_days = 5; //@todo create a setting to configure this period.
  39.  
  40. //@todo: Add a flag to subscriptions with sent communications. Then improve the conditions below to prevent multiple emails.
  41.  
  42. do_action(
  43. 'ms_check_membership_status-' . $this->status,
  44. $this,
  45. $remaining_days,
  46. $remaining_trial_days
  47. );
  48.  
  49. // Update the Subscription status.
  50. $next_status = $this->calculate_status( null );
  51.  
  52. switch ( $next_status ) {
  53. case self::STATUS_TRIAL:
  54. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_TRIAL )
  55. && MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_AUTO_MSGS_PLUS )
  56. ) {
  57. // Send trial end communication.
  58. $comm = $comms[ MS_Model_Communication::COMM_TYPE_BEFORE_TRIAL_FINISHES ];
  59.  
  60. if ( $comm->enabled ) {
  61. $days = MS_Helper_Period::get_period_in_days(
  62. $comm->period['period_unit'],
  63. $comm->period['period_type']
  64. );
  65. //@todo: This will send out the reminder multiple times on the reminder-day (4 times or more often)
  66. if ( $days == $remaining_trial_days ) {
  67. $comm->add_to_queue( $this->id );
  68. MS_Model_Event::save_event(
  69. MS_Model_Event::TYPE_MS_BEFORE_TRIAL_FINISHES,
  70. $this
  71. );
  72. }
  73. }
  74. }
  75.  
  76. // Check for card expiration
  77. $gateway = $this->get_gateway();
  78. $gateway->check_card_expiration( $this );
  79. break;
  80.  
  81. case self::STATUS_TRIAL_EXPIRED:
  82. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_TRIAL ) ) {
  83. // Mark the trial period as completed. $this->save() is below.
  84. $this->trial_period_completed = true;
  85.  
  86. // Request payment to the gateway (for gateways that allows it).
  87. $gateway = $this->get_gateway();
  88.  
  89. /*
  90. * The subscription will be either automatically activated
  91. * or set to pending.
  92. *
  93. * Important: Set trial_period_completed=true before calling
  94. * request_payment()!
  95. */
  96. if ( $gateway->request_payment( $this ) ) {
  97. $next_status = self::STATUS_ACTIVE;
  98. $this->status = $next_status;
  99. $this->config_period(); // Needed because of status change.
  100. }
  101.  
  102. // Check for card expiration
  103. $gateway->check_card_expiration( $this );
  104.  
  105. // Deactivate expired memberships after a period of time.
  106. if ( $deactivate_trial_expired_after_days < - $remaining_trial_days ) {
  107. $this->deactivate_membership();
  108. }
  109. }
  110. break;
  111.  
  112. case self::STATUS_ACTIVE:
  113. case self::STATUS_EXPIRED:
  114. case self::STATUS_CANCELED:
  115. /*
  116. * Make sure the expire date has a correct value, in case the user
  117. * changed the payment_type of the parent membership after this
  118. * subscription was created.
  119. */
  120. if ( $this->payment_type != $membership->payment_type ) {
  121. $this->payment_type = $membership->payment_type;
  122.  
  123. switch ( $this->payment_type ) {
  124. case MS_Model_Membership::PAYMENT_TYPE_PERMANENT:
  125. $this->expire_date = false;
  126. break;
  127.  
  128. default:
  129. // Either keep the current expire date (if valid) or
  130. // calculate a new expire date, based on current date.
  131. if ( ! $this->expire_date ) {
  132. $this->expire_date = $this->calc_expire_date(
  133. MS_Helper_Period::current_date()
  134. );
  135. }
  136.  
  137. break;
  138. }
  139.  
  140. // Recalculate the days until the subscription expires.
  141. $remaining_days = $this->get_remaining_period();
  142.  
  143. // Recalculate the new Subscription status.
  144. $next_status = $this->calculate_status();
  145. }
  146.  
  147. /*
  148. * Only "Recurring" memberships will ever try to automatically
  149. * renew the subscription. All other types will expire when the
  150. * end date is reached.
  151. */
  152. $auto_renew = ($membership->payment_type == MS_Model_Membership::PAYMENT_TYPE_RECURRING);
  153. $deactivate = false;
  154. $invoice = null;
  155.  
  156. if ( $auto_renew && $membership->pay_cycle_repetitions > 0 ) {
  157. /*
  158. * The membership has a payment-repetition limit.
  159. * When this limit is reached then we do not auto-renew the
  160. * subscription but expire it.
  161. */
  162. $payments = $this->get_payments();
  163. if ( count( $payments ) >= $membership->pay_cycle_repetitions ) {
  164. $auto_renew = false;
  165. }
  166. }
  167.  
  168. if ( $auto_renew ) {
  169. if ( $remaining_days < $invoice_before_days ) {
  170. // Create a new invoice.
  171. $invoice = $this->get_next_invoice();
  172. } else {
  173. $invoice = $this->get_current_invoice();
  174. }
  175. } else {
  176. $invoice = $this->get_current_invoice();
  177. }
  178.  
  179. // Advanced communications Add-on.
  180. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_AUTO_MSGS_PLUS ) ) {
  181. // Before finishes communication.
  182. $comm = $comms[ MS_Model_Communication::COMM_TYPE_BEFORE_FINISHES ];
  183. $days = MS_Helper_Period::get_period_in_days(
  184. $comm->period['period_unit'],
  185. $comm->period['period_type']
  186. );
  187. if ( $days == $remaining_days ) {
  188. $comm->add_to_queue( $this->id );
  189. MS_Model_Event::save_event(
  190. MS_Model_Event::TYPE_MS_BEFORE_FINISHES,
  191. $this
  192. );
  193. }
  194.  
  195. // After finishes communication.
  196. $comm = $comms[ MS_Model_Communication::COMM_TYPE_AFTER_FINISHES ];
  197. $days = MS_Helper_Period::get_period_in_days(
  198. $comm->period['period_unit'],
  199. $comm->period['period_type']
  200. );
  201.  
  202. if ( $remaining_days < 0 && $days == abs( $remaining_days ) ) {
  203. $comm->add_to_queue( $this->id );
  204. MS_Model_Event::save_event(
  205. MS_Model_Event::TYPE_MS_AFTER_FINISHES,
  206. $this
  207. );
  208. }
  209.  
  210. // Before payment due.
  211. $comm = $comms[ MS_Model_Communication::COMM_TYPE_BEFORE_PAYMENT_DUE ];
  212. $days = MS_Helper_Period::get_period_in_days(
  213. $comm->period['period_unit'],
  214. $comm->period['period_type']
  215. );
  216. $invoice_days = MS_Helper_Period::subtract_dates(
  217. $invoice->due_date,
  218. MS_Helper_Period::current_date()
  219. );
  220.  
  221. if ( MS_Model_Invoice::STATUS_BILLED == $invoice->status
  222. && $days == $invoice_days
  223. ) {
  224. $comm->add_to_queue( $this->id );
  225. MS_Model_Event::save_event( MS_Model_Event::TYPE_PAYMENT_BEFORE_DUE, $this );
  226. }
  227.  
  228. // After payment due event
  229. $comm = $comms[ MS_Model_Communication::COMM_TYPE_AFTER_PAYMENT_DUE ];
  230. $days = MS_Helper_Period::get_period_in_days(
  231. $comm->period['period_unit'],
  232. $comm->period['period_type']
  233. );
  234. $invoice_days = MS_Helper_Period::subtract_dates(
  235. $invoice->due_date,
  236. MS_Helper_Period::current_date()
  237. );
  238.  
  239. if ( MS_Model_Invoice::STATUS_BILLED == $invoice->status
  240. && $days == $invoice_days
  241. ) {
  242. $comm->add_to_queue( $this->id );
  243. MS_Model_Event::save_event( MS_Model_Event::TYPE_PAYMENT_AFTER_DUE, $this );
  244. }
  245. } // -- End of advanced communications Add-on
  246.  
  247. // Subscription ended. See if we can renew it.
  248. if ( $remaining_days <= 0 ) {
  249. if ( $auto_renew ) {
  250. /*
  251. * The membership can be renewed. Try to renew it
  252. * automatically by requesting the next payment from the
  253. * payment gateway (only works if gateway supports this)
  254. */
  255. $gateway = $this->get_gateway();
  256. $gateway->check_card_expiration( $this );
  257. $gateway->request_payment( $this );
  258.  
  259. // Check if the payment was successful.
  260. $remaining_days = $this->get_remaining_period();
  261. }
  262.  
  263. /*
  264. * User did not renew the membership. Give him some time to
  265. * react before restricting his access.
  266. */
  267. if ( $deactivate_expired_after_days < - $remaining_days ) {
  268. $deactivate = true;
  269. }
  270. }
  271.  
  272. $next_status = $this->calculate_status( null );
  273.  
  274. /*
  275. * When the subscription expires the first time then create a
  276. * new event that triggers the "Expired" email.
  277. */
  278. if ( self::STATUS_EXPIRED == $next_status && $next_status != $this->status ) {
  279. MS_Model_Event::save_event(
  280. MS_Model_Event::TYPE_MS_EXPIRED,
  281. $this
  282. );
  283. }
  284. elseif ( $deactivate ) {
  285. $this->deactivate_membership();
  286. $next_status = $this->status;
  287.  
  288. // Move membership to configured membership.
  289. $membership = $this->get_membership();
  290.  
  291. $new_membership = MS_Factory::load(
  292. 'MS_Model_Membership',
  293. $membership->on_end_membership_id
  294. );
  295.  
  296. if ( $new_membership->is_valid() ) {
  297. $member = MS_Factory::load( 'MS_Model_Member', $this->user_id );
  298. $new_subscription = $member->add_membership(
  299. $membership->on_end_membership_id,
  300. $this->gateway_id
  301. );
  302.  
  303. MS_Model_Event::save_event(
  304. MS_Model_Event::TYPE_MS_MOVED,
  305. $new_subscription
  306. );
  307.  
  308. /*
  309. * If the new membership is paid we want that the user
  310. * confirms the payment in his account. So we set it
  311. * to "Pending" first.
  312. */
  313. if ( ! $new_membership->is_free() ) {
  314. $new_subscription->status = self::STATUS_PENDING;
  315. }
  316. }
  317. }
  318. break;
  319.  
  320. case self::STATUS_DEACTIVATED:
  321. /*
  322. * A subscription was finally deactivated.
  323. * Lets check if the member has any other active subscriptions,
  324. * or (if not) his account should be deactivated.
  325. *
  326. * First get a list of all subscriptions that do not have status
  327. * Pending / Deactivated.
  328. */
  329. $subscriptions = self::get_subscriptions(
  330. array( 'user_id' => $this->user_id )
  331. );
  332.  
  333. // Check if there is a subscription that keeps the user active.
  334. $deactivate = true;
  335. foreach ( $subscriptions as $item ) {
  336. if ( $item->id == $this->id ) { continue; }
  337. $deactivate = false;
  338. }
  339.  
  340. if ( $deactivate ) {
  341. $member = $this->get_member();
  342. $member->is_member = false;
  343. $member->save();
  344. }
  345. break;
  346.  
  347. case self::STATUS_PENDING:
  348. default:
  349. // Do nothing.
  350. break;
  351. }
  352.  
  353. // Save the new status.
  354. $this->status = $next_status;
  355. $this->save();
  356.  
  357. // Save the changed email queue.
  358. foreach ( $comms as $comm ) {
  359. $comm->save();
  360. }
  361.  
  362. do_action(
  363. 'ms_model_relationship_check_membership_status_after',
  364. $this
  365. );
  366. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement