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

  1. <?php 
  2. /** 
  3. * Membership Simulation model. 
  4. * 
  5. * Persisted by parent class MS_Model_Transient. 
  6. * 
  7. * @since 1.0.0 
  8. * 
  9. * @package Membership2 
  10. * @subpackage Model 
  11. */ 
  12. class MS_Model_Simulate extends MS_Model_Transient { 
  13.  
  14. /** 
  15. * The membership ID to simulate. 
  16. * 
  17. * @since 1.0.0 
  18. * 
  19. * @var int 
  20. */ 
  21. protected $membership_id = null; 
  22.  
  23. /** 
  24. * Flag, if the simulation should display a datepicker or not. 
  25. * 
  26. * @since 1.0.0 
  27. * @var bool 
  28. */ 
  29. protected $datepicker = false; 
  30.  
  31. /** 
  32. * The date to simulate. 
  33. * 
  34. * @since 1.0.0 
  35. * 
  36. * @var string 
  37. */ 
  38. protected $date; 
  39.  
  40. /** 
  41. * Holds a reference to the simulated subscription. 
  42. * 
  43. * @var MS_Model_Relationship 
  44. */ 
  45. protected $_subscription = null; 
  46.  
  47. /** 
  48. * Determines if the current user is permitted to even think about using 
  49. * simulation. If not allowed, then most of this class will not be used. 
  50. * 
  51. * @since 1.0.0 
  52. * @return bool 
  53. */ 
  54. public static function can_simulate() { 
  55. if ( defined( 'DOING_CRON' ) && DOING_CRON ) { 
  56. // No simulation during cron jobs... 
  57. return false; 
  58.  
  59. if ( MS_Model_Member::is_admin_user() ) { 
  60. return true; 
  61.  
  62. return false; 
  63.  
  64. /** 
  65. * Called after loading model data. 
  66. * 
  67. * @since 1.0.0 
  68. */ 
  69. public function after_load() { 
  70. if ( ! $this->can_simulate() ) { return false; } 
  71.  
  72. if ( $this->is_simulating() ) { 
  73. if ( empty( $this->date ) ) { 
  74. $this->date = MS_Helper_Period::current_date(); 
  75.  
  76. add_filter( 
  77. 'pre_site_option_site_admins',  
  78. array( $this, 'admin_filter' ) 
  79. ); 
  80.  
  81. add_filter( 
  82. 'ms_model_relationship_get_subscriptions',  
  83. array( $this, 'add_simulation_membership' ),  
  84. 10, 2 
  85. ); 
  86.  
  87. /** 
  88. * Makes the current user a non-admin user during simulation 
  89. * 
  90. * @since 1.0.0 
  91. * @param string $result Set to False to use default WordPress value. 
  92. * @return string Empty value means "no Administrator on this installation". 
  93. */ 
  94. public function admin_filter( $result ) { 
  95. return ''; 
  96.  
  97. /** 
  98. * Add the simulated relationship to the current users memberships. 
  99. * 
  100. * @since 1.0.0 
  101. */ 
  102. public function add_simulation_membership( $subscriptions ) { 
  103. $subscription = false; 
  104.  
  105. if ( ! isset( $subscriptions[ $this->membership_id ] ) ) { 
  106. $this->start_simulation(); 
  107.  
  108. $subscription = MS_Model_Relationship::create_ms_relationship( 
  109. $this->membership_id,  
  110. 0,  
  111. 'simulation' 
  112. ); 
  113.  
  114. if ( is_a( $subscription, 'MS_Model_Relationship' ) ) { 
  115. $membership = $subscription->get_membership(); 
  116. if ( MS_Model_Membership::PAYMENT_TYPE_PERMANENT == $membership->payment_type 
  117. || MS_Model_Membership::PAYMENT_TYPE_RECURRING == $membership->payment_type 
  118. ) { 
  119. $subscription->expire_date = '2999-12-31'; 
  120.  
  121. $key = 'ms_model_relationship--1'; 
  122. MS_Factory::set_singleton( $subscription, $key ); 
  123.  
  124. $this->_subscription = $subscription; 
  125. $subscriptions[ $this->membership_id ] = $subscription; 
  126.  
  127. return $subscriptions; 
  128.  
  129. /** 
  130. * Check simulating status 
  131. * 
  132. * @since 1.0.0 
  133. * 
  134. * @return bool True if currently simulating a membership. 
  135. */ 
  136. public function is_simulating() { 
  137. if ( ! self::can_simulate() ) { 
  138. return false; 
  139.  
  140. return ! empty( $this->membership_id ); 
  141.  
  142. /** 
  143. * Start simulation date. 
  144. * 
  145. * @since 1.0.0 
  146. */ 
  147. private function start_simulation() { 
  148. if ( ! self::can_simulate() ) { 
  149. return false; 
  150.  
  151. if ( $this->datepicker ) { 
  152. $this->add_filter( 
  153. 'ms_helper_period_current_date',  
  154. 'simulate_date_filter' 
  155. ); 
  156.  
  157. // Display some infos on the simulation. 
  158. $this->add_filter( 
  159. 'shutdown',  
  160. 'simulation_infos' 
  161. ); 
  162.  
  163. /** 
  164. * Simulate date. 
  165. * 
  166. * Used Hooks filter/actions: 
  167. * - ms_helper_period_current_date 
  168. * 
  169. * @since 1.0.0 
  170. * 
  171. * @param string $current_date The date to filter. 
  172. * @return string The filtered date. 
  173. */ 
  174. public function simulate_date_filter( $current_date ) { 
  175. if ( ! empty( $this->date ) ) { 
  176. $current_date = $this->date; 
  177.  
  178. return $current_date; 
  179.  
  180. /** 
  181. * Reset simulation. 
  182. * 
  183. * @since 1.0.0 
  184. */ 
  185. public function reset_simulation() { 
  186. if ( null === $this->membership_id ) { return; } 
  187.  
  188. $this->membership_id = null; 
  189. $this->date = null; 
  190. $this->subscription = null; 
  191.  
  192. $this->remove_filter( 
  193. 'ms_helper_period_current_date',  
  194. 'simulate_date_filter' 
  195. ); 
  196.  
  197. $this->save(); 
  198.  
  199. /** 
  200. * Checks if the currently simulated membership needs a datepicker or not. 
  201. * 
  202. * @since 1.0.0 
  203. * 
  204. * @return string True if a datepicker is needed. 
  205. */ 
  206. public function needs_datepicker() { 
  207. $membership = MS_Factory::load( 
  208. 'MS_Model_Membership',  
  209. $this->membership_id 
  210. ); 
  211.  
  212. $m_type = $membership->type; 
  213. $p_type = $membership->payment_type; 
  214. $rep_end = $membership->pay_cycle_repetitions > 0; 
  215. $date_specific = false; 
  216.  
  217. if ( MS_Model_Membership::TYPE_DRIPPED === $m_type ) { $date_specific = true; } 
  218. elseif ( MS_Model_Membership::PAYMENT_TYPE_FINITE === $p_type ) { $date_specific = true; } 
  219. elseif ( MS_Model_Membership::PAYMENT_TYPE_DATE_RANGE === $p_type ) { $date_specific = true; } 
  220. elseif ( MS_Model_Membership::PAYMENT_TYPE_RECURRING === $p_type && $rep_end ) { $date_specific = true; } 
  221.  
  222. $this->datepicker = $date_specific; 
  223.  
  224. return apply_filters( 
  225. 'ms_model_simulate_needs_datepicker',  
  226. $this->datepicker,  
  227. $this 
  228. ); 
  229.  
  230. /** 
  231. * Display some infos on the page on the current simulation 
  232. * 
  233. * @since 1.0.0 
  234. */ 
  235. public function simulation_infos() { 
  236. if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { return false; } 
  237. if ( defined( 'DOING_CRON' ) && DOING_CRON ) { return false; } 
  238.  
  239. /** 
  240. * The following condition is needed to bypass Upfront virtual pages. 
  241. * By checking for the WordPress filters we can find out if the current 
  242. * page is rendered by WordPress or not (...not means Upfront) 
  243. */ 
  244. $show_infos = true; 
  245. if ( ! is_admin() && ! did_action( 'wp_print_footer_scripts' ) ) { 
  246. $show_infos = false; 
  247. } elseif ( is_admin() && ! did_action( 'admin_print_footer_scripts' ) ) { 
  248. $show_infos = false; 
  249.  
  250. if ( $show_infos ) { 
  251. $data = array(); 
  252. $data['membership_id'] = $this->membership_id; 
  253. $data['subscription'] = $this->_subscription; 
  254. $data['simulate_date'] = $this->date; 
  255. $data['datepicker'] = $this->datepicker; 
  256.  
  257. $view = MS_Factory::create( 'MS_View_Adminbar' ); 
  258. $view->data = apply_filters( 'ms_view_admin_bar_data', $data ); 
  259. $html = $view->to_html(); 
  260.  
  261. echo $html; 
  262.  
  263. /** 
  264. * Returns property associated with the render. 
  265. * 
  266. * @since 1.0.0 
  267. * 
  268. * @param string $property The name of a property. 
  269. * @return mixed Returns mixed value of a property or NULL if a property doesn't exist. 
  270. */ 
  271. public function __get( $property ) { 
  272. $value = null; 
  273.  
  274. if ( property_exists( $this, $property ) ) { 
  275. switch ( $property ) { 
  276. case 'date': 
  277. if ( empty( $this->date ) ) { 
  278. $this->date = MS_Helper_Period::current_date(); 
  279. $value = $this->date; 
  280. break; 
  281.  
  282. default: 
  283. $value = $this->$property; 
  284. break; 
  285.  
  286. return apply_filters( 
  287. 'ms_model_simulate__get',  
  288. $value,  
  289. $property,  
  290. $this 
  291. ); 
  292.  
  293. /** 
  294. * Validate specific property before set. 
  295. * 
  296. * @since 1.0.0 
  297. * 
  298. * @param string $name The name of a property to associate. 
  299. * @param mixed $value The value of a property. 
  300. */ 
  301. public function __set( $property, $value ) { 
  302. if ( property_exists( $this, $property ) ) { 
  303. switch ( $property ) { 
  304. case 'membership_id': 
  305. $this->membership_id = null; 
  306. $id = absint( $value ); 
  307. if ( ! empty( $id ) ) { 
  308. if ( MS_Model_Membership::is_valid_membership( $id ) ) { 
  309. $this->membership_id = $id; 
  310. $this->needs_datepicker(); 
  311. break; 
  312.  
  313. case 'date': 
  314. if ( $date = $this->validate_date( $value ) ) { 
  315. $this->date = $value; 
  316. break; 
  317.  
  318. default: 
  319. $this->$property = $value; 
  320. break; 
  321.  
  322. do_action( 
  323. 'ms_model_simulate__set_after',  
  324. $property,  
  325. $value,  
  326. $this 
  327. ); 
  328.  
  329. /** 
  330. * Check if property isset. 
  331. * 
  332. * @since 1.0.0 
  333. * @internal 
  334. * 
  335. * @param string $property The name of a property. 
  336. * @return mixed Returns true/false. 
  337. */ 
  338. public function __isset( $property ) { 
  339. return isset($this->$property); 
  340. }  
.