MS_Controller_Gateway

Gateway controller.

Defined (1)

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

/app/controller/class-ms-controller-gateway.php  
  1. class MS_Controller_Gateway extends MS_Controller { 
  2.  
  3. /** 
  4. * AJAX action constants. 
  5. * @since 1.0.0 
  6. * @var string 
  7. */ 
  8. const AJAX_ACTION_TOGGLE_GATEWAY = 'toggle_gateway'; 
  9. const AJAX_ACTION_UPDATE_GATEWAY = 'update_gateway'; 
  10.  
  11. /** 
  12. * Allowed actions to execute in template_redirect hook. 
  13. * @since 1.0.0 
  14. * @var string 
  15. */ 
  16. private $allowed_actions = array( 'update_card', 'purchase_button' ); 
  17.  
  18. /** 
  19. * Prepare the gateway controller. 
  20. * @since 1.0.0 
  21. */ 
  22. public function __construct() { 
  23. parent::__construct(); 
  24.  
  25. $this->add_action( 'template_redirect', 'process_actions', 1 ); 
  26.  
  27. $this->add_action( 'ms_controller_gateway_settings_render_view', 'gateway_settings_edit' ); 
  28.  
  29. $this->add_action( 'ms_view_shortcode_invoice_purchase_button', 'purchase_button', 10, 2 ); 
  30. $this->add_action( 'ms_view_frontend_payment_purchase_button', 'purchase_button', 10, 2 ); 
  31.  
  32. $this->add_action( 'ms_controller_frontend_signup_gateway_form', 'gateway_form_mgr', 1 ); 
  33. $this->add_action( 'ms_controller_frontend_signup_process_purchase', 'process_purchase', 1 ); 
  34. $this->add_filter( 'ms_view_shortcode_membershipsignup_cancel_button', 'cancel_button', 10, 2 ); 
  35.  
  36. $this->add_action( 'ms_view_shortcode_account_card_info', 'card_info' ); 
  37.  
  38. $this->add_action( 'pre_get_posts', 'handle_payment_return', 1 ); 
  39.  
  40. $this->add_action( 'ms_controller_frontend_enqueue_scripts', 'enqueue_scripts' ); 
  41.  
  42. $this->add_ajax_action( self::AJAX_ACTION_TOGGLE_GATEWAY, 'toggle_ajax_action' ); 
  43. $this->add_ajax_action( self::AJAX_ACTION_UPDATE_GATEWAY, 'ajax_action_update_gateway' ); 
  44.  
  45. /** 
  46. * Handle URI actions for registration. 
  47. * Matches returned 'action' to method to execute. 
  48. * Related action hooks: 
  49. * - template_redirect 
  50. * @since 1.0.0 
  51. */ 
  52. public function process_actions() { 
  53. $action = $this->get_action(); 
  54.  
  55. /** 
  56. * If $action is set, then call relevant method. 
  57. * Methods: 
  58. * @see $allowed_actions property 
  59. */ 
  60. if ( ! empty( $action ) 
  61. && method_exists( $this, $action ) 
  62. && in_array( $action, $this->allowed_actions ) 
  63. ) { 
  64. $this->$action(); 
  65.  
  66. /** 
  67. * Handle Ajax toggle action. 
  68. * Related action hooks: 
  69. * - wp_ajax_toggle_gateway 
  70. * @since 1.0.0 
  71. */ 
  72. public function toggle_ajax_action() { 
  73. $msg = 0; 
  74.  
  75. $fields = array( 'gateway_id' ); 
  76. if ( $this->verify_nonce() 
  77. && self::validate_required( $fields ) 
  78. && $this->is_admin_user() 
  79. ) { 
  80. $msg = $this->gateway_list_do_action( 
  81. 'toggle_activation',  
  82. array( $_POST['gateway_id'] ) 
  83. ); 
  84.  
  85. wp_die( $msg ); 
  86.  
  87. /** 
  88. * Handle Ajax update gateway action. 
  89. * Related action hooks: 
  90. * - wp_ajax_update_gateway 
  91. * @since 1.0.0 
  92. */ 
  93. public function ajax_action_update_gateway() { 
  94. $msg = MS_Helper_Settings::SETTINGS_MSG_NOT_UPDATED; 
  95.  
  96. $fields = array( 'action', 'gateway_id', 'field', 'value' ); 
  97. if ( $this->verify_nonce() 
  98. && self::validate_required( $fields ) 
  99. && $this->is_admin_user() 
  100. ) { 
  101. lib2()->array->strip_slashes( $_POST, 'value' ); 
  102.  
  103. $msg = $this->gateway_list_do_action( 
  104. $_POST['action'],  
  105. array( $_POST['gateway_id'] ),  
  106. array( $_POST['field'] => $_POST['value'] ) 
  107. ); 
  108.  
  109. wp_die( $msg ); 
  110.  
  111. /** 
  112. * Show gateway settings page. 
  113. * Related action hooks: 
  114. * - ms_controller_gateway_settings_render_view 
  115. * @since 1.0.0 
  116. */ 
  117. public function gateway_settings_edit( $gateway_id ) { 
  118. if ( ! empty( $gateway_id ) 
  119. && MS_Model_Gateway::is_valid_gateway( $gateway_id ) 
  120. ) { 
  121. switch ( $gateway_id ) { 
  122. case MS_Gateway_Manual::ID: 
  123. $view = MS_Factory::create( 'MS_Gateway_Manual_View_Settings' ); 
  124. break; 
  125.  
  126. case MS_Gateway_Paypalsingle::ID: 
  127. $view = MS_Factory::create( 'MS_Gateway_Paypalsingle_View_Settings' ); 
  128. break; 
  129.  
  130. case MS_Gateway_Paypalstandard::ID: 
  131. $view = MS_Factory::create( 'MS_Gateway_Paypalstandard_View_Settings' ); 
  132. break; 
  133.  
  134. case MS_Gateway_Authorize::ID: 
  135. $view = MS_Factory::create( 'MS_Gateway_Authorize_View_Settings' ); 
  136. break; 
  137.  
  138. case MS_Gateway_Stripe::ID: 
  139. $view = MS_Factory::create( 'MS_Gateway_Stripe_View_Settings' ); 
  140. break; 
  141.  
  142. default: 
  143. // Empty form... 
  144. $view = MS_Factory::create( 'MS_View' ); 
  145. break; 
  146.  
  147. $data = array( 
  148. 'model' => MS_Model_Gateway::factory( $gateway_id ),  
  149. 'action' => 'edit',  
  150. ); 
  151.  
  152. $view->data = apply_filters( 
  153. 'ms_gateway_view_settings_edit_data',  
  154. $data 
  155. ); 
  156. $view = apply_filters( 
  157. 'ms_gateway_view_settings_edit',  
  158. $view,  
  159. $gateway_id 
  160. ); 
  161.  
  162. $view->render(); 
  163.  
  164. /** 
  165. * Handle Payment Gateway list actions. 
  166. * @since 1.0.0 
  167. * @param string $action The action to execute. 
  168. * @param int[] $gateways The gateways IDs to process. 
  169. * @param mixed[] $fields The data to process. 
  170. */ 
  171. public function gateway_list_do_action( $action, $gateways, $fields = null ) { 
  172. $msg = MS_Helper_Settings::SETTINGS_MSG_NOT_UPDATED; 
  173. if ( ! $this->is_admin_user() ) { 
  174. return $msg; 
  175.  
  176. foreach ( $gateways as $gateway_id ) { 
  177. $gateway = MS_Model_Gateway::factory( $gateway_id ); 
  178.  
  179. switch ( $action ) { 
  180. case 'toggle_activation': 
  181. $gateway->active = ! $gateway->active; 
  182. $gateway->save(); 
  183. $msg = MS_Helper_Settings::SETTINGS_MSG_UPDATED; 
  184.  
  185. /** 
  186. * Hook called after a gateway-status was toggled. 
  187. * @since 2.0.0 
  188. */ 
  189. do_action( 'ms_gateway_toggle_' . $gateway_id, $gateway ); 
  190. break; 
  191.  
  192. case 'edit': 
  193. case 'update_gateway': 
  194. foreach ( $fields as $field => $value ) { 
  195. $gateway->$field = trim( $value ); 
  196. $gateway->save(); 
  197.  
  198. /** 
  199. * $settings->is_global_payments_set is used to hide global 
  200. * payment settings in the membership setup payment step 
  201. */ 
  202. if ( $gateway->is_configured() ) { 
  203. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  204. $settings->is_global_payments_set = true; 
  205. $settings->save(); 
  206. $msg = MS_Helper_Settings::SETTINGS_MSG_UPDATED; 
  207. } else { 
  208. $msg = MS_Helper_Settings::SETTINGS_MSG_UNCONFIGURED; 
  209.  
  210. /** 
  211. * Hook called after a gateway-settings were modified. 
  212. * @since 2.0.0 
  213. */ 
  214. do_action( 'ms_gateway_changed_' . $gateway_id, $gateway ); 
  215. break; 
  216.  
  217. return apply_filters( 
  218. 'ms_controller_gateway_gateway_list_do_action',  
  219. $msg,  
  220. $action,  
  221. $gateways,  
  222. $fields,  
  223. $this 
  224. ); 
  225.  
  226. /** 
  227. * Show gateway purchase button. 
  228. * Related action hooks: 
  229. * - ms_view_frontend_payment_purchase_button 
  230. * - ms_view_shortcode_invoice_purchase_button 
  231. * @since 1.0.0 
  232. */ 
  233. public function purchase_button( $subscription, $invoice ) { 
  234. // Get only active gateways 
  235. $gateways = MS_Model_Gateway::get_gateways( true ); 
  236. $data = array(); 
  237.  
  238. $membership = $subscription->get_membership(); 
  239. $is_free = false; 
  240. if ( $membership->is_free() ) { $is_free = true; } 
  241. elseif ( 0 == $invoice->total ) { $is_free = true; } 
  242. elseif ( $invoice->uses_trial ) { $is_free = true; } 
  243.  
  244. // show gateway purchase button for every active gateway 
  245. foreach ( $gateways as $gateway ) { 
  246. $view = null; 
  247.  
  248. // Skip gateways that are not configured. 
  249. if ( ! $gateway->is_configured() ) { continue; } 
  250. if ( ! $membership->can_use_gateway( $gateway->id ) ) { continue; } 
  251.  
  252. $data['ms_relationship'] = $subscription; 
  253. $data['gateway'] = $gateway; 
  254. $data['step'] = MS_Controller_Frontend::STEP_PROCESS_PURCHASE; 
  255.  
  256. // Free membership, show only free gateway 
  257. if ( $is_free ) { 
  258. if ( MS_Gateway_Free::ID !== $gateway->id ) { 
  259. continue; 
  260. // Skip free gateway 
  261. elseif ( MS_Gateway_Free::ID === $gateway->id ) { 
  262. continue; 
  263.  
  264. $view_class = get_class( $gateway ) . '_View_Button'; 
  265. $view = MS_Factory::create( $view_class ); 
  266.  
  267. if ( MS_Gateway_Authorize::ID == $gateway->id ) { 
  268. /** 
  269. * set additional step for authorize.net (gateway specific form) 
  270. * @todo change to use popup, instead of another step (like stripe) 
  271. */ 
  272. $data['step'] = 'gateway_form'; 
  273.  
  274. if ( ! empty( $view ) ) { 
  275. $view = apply_filters( 
  276. 'ms_gateway_view_button',  
  277. $view,  
  278. $gateway->id 
  279. ); 
  280.  
  281. $view->data = apply_filters( 
  282. 'ms_gateway_view_button_data',  
  283. $data,  
  284. $gateway->id 
  285. ); 
  286.  
  287. $html = apply_filters( 
  288. 'ms_controller_gateway_purchase_button_'. $gateway->id,  
  289. $view->to_html(),  
  290. $subscription,  
  291. $this 
  292. ); 
  293.  
  294. echo '' . $html; 
  295.  
  296.  
  297. /** 
  298. * Show gateway purchase button. 
  299. * Related action hooks: 
  300. * - ms_view_shortcode_membershipsignup_cancel_button 
  301. * @since 1.0.0 
  302. */ 
  303. public function cancel_button( $button, $ms_relationship ) { 
  304. $view = null; 
  305. $data = array(); 
  306. $data['ms_relationship'] = $ms_relationship; 
  307. $new_button = null; 
  308.  
  309. switch ( $ms_relationship->gateway_id ) { 
  310. case MS_Gateway_Paypalstandard::ID: 
  311. $view = MS_Factory::create( 'MS_Gateway_Paypalstandard_View_Cancel' ); 
  312. $data['gateway'] = $ms_relationship->get_gateway(); 
  313. break; 
  314.  
  315. case MS_Gateway_Authorize::ID: 
  316. case MS_Gateway_Paypalsingle::ID: 
  317. case MS_Gateway_Stripe::ID: 
  318. case MS_Gateway_Free::ID: 
  319. case MS_Gateway_Manual::ID: 
  320. default: 
  321. break; 
  322. $view = apply_filters( 'ms_gateway_view_cancel_button', $view ); 
  323.  
  324. if ( ! empty( $view ) ) { 
  325. $view->data = apply_filters( 
  326. 'ms_gateway_view_cancel_button_data',  
  327. $data 
  328. ); 
  329. $new_button = $view->get_button(); 
  330.  
  331. if ( ! $new_button ) { 
  332. $new_button = $button; 
  333.  
  334. return apply_filters( 
  335. 'ms_controller_gateway_cancel_button',  
  336. $new_button,  
  337. $ms_relationship,  
  338. $this 
  339. ); 
  340.  
  341. /** 
  342. * Set hook to handle gateway extra form to commit payments. 
  343. * Related action hooks: 
  344. * - ms_controller_frontend_signup_gateway_form 
  345. * @since 1.0.0 
  346. */ 
  347. public function gateway_form_mgr() { 
  348. // Display gateway form 
  349. $this->add_filter( 'the_content', 'gateway_form', 10 ); 
  350.  
  351. // Enqueue styles and scripts used 
  352. $this->add_action( 'wp_enqueue_scripts', 'enqueue_scripts' ); 
  353.  
  354. /** 
  355. * Handles gateway extra form to commit payments. 
  356. * Related filter hooks: 
  357. * - the_content 
  358. * @since 1.0.0 
  359. * @param string $content The page content to filter. 
  360. * @return string The filtered content. 
  361. */ 
  362. public function gateway_form( $content ) { 
  363. $data = array(); 
  364.  
  365. $fields = array( 'gateway', 'ms_relationship_id' ); 
  366. if ( self::validate_required( $fields ) 
  367. && MS_Model_Gateway::is_valid_gateway( $_POST['gateway'] ) 
  368. ) { 
  369. $data['gateway'] = $_POST['gateway']; 
  370. $data['ms_relationship_id'] = $_POST['ms_relationship_id']; 
  371.  
  372. $ms_relationship = MS_Factory::load( 
  373. 'MS_Model_Relationship',  
  374. $_POST['ms_relationship_id'] 
  375. ); 
  376.  
  377. switch ( $_POST['gateway'] ) { 
  378. case MS_Gateway_Authorize::ID: 
  379. $member = $ms_relationship->get_member(); 
  380. $view = MS_Factory::create( 'MS_Gateway_Authorize_View_Form' ); 
  381. $gateway = MS_Model_Gateway::factory( MS_Gateway_Authorize::ID ); 
  382. $data['countries'] = $gateway->get_country_codes(); 
  383.  
  384. $data['action'] = $this->get_action(); 
  385.  
  386. if ( 'update_card' == $this->get_action() ) { 
  387. // Only new card option available on update card action. 
  388. $data['cim_profiles'] = array(); 
  389. } else { 
  390. // show existing credit card. 
  391. $data['cim_profiles'] = $gateway->get_cim_profile( $member ); 
  392.  
  393. lib2()->array->strip_slashes( $_POST, 'auth_error' ); 
  394.  
  395. $data['cim_payment_profile_id'] = $gateway->get_cim_payment_profile_id( $member ); 
  396. $data['auth_error'] = ! empty( $_POST['auth_error'] ) ? $_POST['auth_error'] : ''; 
  397. break; 
  398.  
  399. default: 
  400. break; 
  401.  
  402. $view = apply_filters( 'ms_gateway_view_form', $view ); 
  403. $view->data = apply_filters( 'ms_gateway_view_form_data', $data ); 
  404.  
  405. return apply_filters( 
  406. 'ms_controller_gateway_form',  
  407. $view->to_html(),  
  408. $this 
  409. ); 
  410.  
  411. /** 
  412. * Process purchase using gateway. 
  413. * Related Action Hooks: 
  414. * - ms_controller_frontend_signup_process_purchase 
  415. * @since 1.0.0 
  416. */ 
  417. public function process_purchase() { 
  418. $fields = array( 'gateway', 'ms_relationship_id' ); 
  419.  
  420. lib2()->array->equip_request( 'gateway', 'ms_relationship_id' ); 
  421.  
  422. $valid = true; 
  423. $nonce_name = $_REQUEST['gateway'] . '_' . $_REQUEST['ms_relationship_id']; 
  424.  
  425. if ( ! self::validate_required( $fields, 'any' ) ) { 
  426. $valid = false; 
  427. $err = 'GAT-01 (invalid fields)'; 
  428. } elseif ( ! MS_Model_Gateway::is_valid_gateway( $_REQUEST['gateway'] ) ) { 
  429. $valid = false; 
  430. $err = 'GAT-02 (invalid gateway)'; 
  431. } elseif ( ! $this->verify_nonce( $nonce_name, 'any' ) ) { 
  432. $valid = false; 
  433. $err = 'GAT-03 (invalid nonce)'; 
  434.  
  435. if ( $valid ) { 
  436. $subscription = MS_Factory::load( 
  437. 'MS_Model_Relationship',  
  438. $_REQUEST['ms_relationship_id'] 
  439. ); 
  440.  
  441. $gateway_id = $_REQUEST['gateway']; 
  442. $gateway = MS_Model_Gateway::factory( $gateway_id ); 
  443.  
  444. try { 
  445. $invoice = $gateway->process_purchase( $subscription ); 
  446.  
  447. // If invoice is successfully paid, redirect to welcome page. 
  448. if ( $invoice->is_paid() 
  449. || ( $invoice->uses_trial 
  450. && MS_Model_Invoice::STATUS_BILLED == $invoice->status 
  451. ) { 
  452. // Make sure to respect the single-membership rule 
  453. $this->validate_membership_states( $subscription ); 
  454.  
  455. // Redirect user to the Payment-Completed page. 
  456. if ( ! defined( 'IS_UNIT_TEST' ) ) { 
  457. MS_Model_Pages::redirect_to( 
  458. MS_Model_Pages::MS_PAGE_REG_COMPLETE,  
  459. array( 'ms_relationship_id' => $subscription->id ) 
  460. ); 
  461. } else { 
  462. // For manual gateway payments. 
  463. $this->add_action( 'the_content', 'purchase_info_content' ); 
  464. catch ( Exception $e ) { 
  465. MS_Helper_Debug::log( $e->getMessage() ); 
  466.  
  467. switch ( $gateway_id ) { 
  468. case MS_Gateway_Authorize::ID: 
  469. $_POST['auth_error'] = $e->getMessage(); 
  470. // call action to step back 
  471. do_action( 'ms_controller_frontend_signup_gateway_form' ); 
  472. break; 
  473.  
  474. case MS_Gateway_Stripe::ID: 
  475. $_POST['error'] = sprintf( 
  476. __( 'Error: %s', MS_TEXT_DOMAIN ),  
  477. $e->getMessage() 
  478. ); 
  479.  
  480. // Hack to send the error message back to the payment_table. 
  481. MS_Plugin::instance()->controller->controllers['frontend']->add_action( 
  482. 'the_content',  
  483. 'payment_table', 1 
  484. ); 
  485. break; 
  486.  
  487. default: 
  488. do_action( 'ms_controller_gateway_form_error', $e ); 
  489. $this->add_action( 'the_content', 'purchase_error_content' ); 
  490. break; 
  491. } else { 
  492. MS_Helper_Debug::log( 'Error Code ' . $err ); 
  493.  
  494. $this->add_action( 'the_content', 'purchase_error_content' ); 
  495.  
  496. // Hack to show signup page in case of errors 
  497. $ms_page = MS_Model_Pages::get_page( MS_Model_Pages::MS_PAGE_REGISTER ); 
  498.  
  499. if ( $ms_page ) { 
  500. // During unit-testing the $ms_page object might be empty. 
  501. global $wp_query; 
  502. $wp_query->query_vars['page_id'] = $ms_page->ID; 
  503. $wp_query->query_vars['post_type'] = 'page'; 
  504.  
  505. do_action( 
  506. 'ms_controller_gateway_process_purchase_after',  
  507. $this 
  508. ); 
  509.  
  510. /** 
  511. * Make sure that we respect the Single-Membership rule. 
  512. * This rule is active when the "Multiple-Memberships" Add-on is DISABLED. 
  513. * @since 1.0.4 
  514. * @param MS_Model_Relationship $new_relationship 
  515. */ 
  516. protected function validate_membership_states( $new_relationship ) { 
  517. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_MULTI_MEMBERSHIPS ) ) { 
  518. // Multiple memberships allowed. No need to check anything. 
  519. return; 
  520.  
  521. $cancel_these = array( 
  522. MS_Model_Relationship::STATUS_TRIAL,  
  523. MS_Model_Relationship::STATUS_ACTIVE,  
  524. MS_Model_Relationship::STATUS_PENDING,  
  525. ); 
  526.  
  527. $member = $new_relationship->get_member(); 
  528. foreach ( $member->subscriptions as $ms_relationship ) { 
  529. if ( $ms_relationship->id === $new_relationship->id ) { continue; } 
  530. if ( in_array( $ms_relationship->status, $cancel_these ) ) { 
  531. $ms_relationship->cancel_membership(); 
  532.  
  533. /** 
  534. * Show signup page with custom content. 
  535. * This is used by manual gateway (overridden) to show payment info. 
  536. * Related action hooks: 
  537. * @since 1.0.0 
  538. * @param string $content The page content to filter. 
  539. * @return string The filtered content. 
  540. */ 
  541. public function purchase_info_content( $content ) { 
  542. return apply_filters( 
  543. 'ms_controller_gateway_purchase_info_content',  
  544. $content,  
  545. $this 
  546. ); 
  547.  
  548. /** 
  549. * Show error message in the signup page. 
  550. * Related action hooks: 
  551. * @since 1.0.0 
  552. */ 
  553. public function purchase_error_content( $content ) { 
  554. return apply_filters( 
  555. 'ms_controller_gateway_purchase_error_content',  
  556. __( 'Sorry, your signup request has failed. Try again.', MS_TEXT_DOMAIN ),  
  557. $content,  
  558. $this 
  559. ); 
  560.  
  561. /** 
  562. * Handle payment gateway return IPNs. 
  563. * Used by Paypal gateways. 
  564. * A redirection rule is set up in the main MS_Plugin object 
  565. * (protected_content.php): 
  566. * /ms-payment-return/XYZ becomes index.php?paymentgateway=XYZ 
  567. * Related action hooks: 
  568. * - pre_get_posts 
  569. * @todo Review how this works when we use OAuth API's with gateways. 
  570. * @since 1.0.0 
  571. * @param WP_Query $wp_query The WordPress query object 
  572. */ 
  573. public function handle_payment_return( $wp_query ) { 
  574. // Do not check custom loops. 
  575. if ( ! $wp_query->is_main_query() ) { return; } 
  576.  
  577. if ( ! empty( $wp_query->query_vars['paymentgateway'] ) ) { 
  578. $gateway = $wp_query->query_vars['paymentgateway']; 
  579.  
  580. // Handle payment-responses from imported membership subscriptions. 
  581. if ( MS_Model_Import_Membership::did_import() ) { 
  582. if ( 'paypalsolo' == $gateway ) { $gateway = 'paypalsingle'; } 
  583. if ( 'paypalexpress' == $gateway ) { $gateway = 'paypalstandard'; } 
  584.  
  585. /** 
  586. * In 1.1.0 the underscore in payment gateway names was removed. 
  587. * To compensate for this we need to continue listen to these old 
  588. * gateway-names. 
  589. */ 
  590. switch ( $gateway ) { 
  591. case 'paypal_single': $gateway = 'paypalsingle'; break; 
  592. case 'paypal_standard': $gateway = 'paypalstandard'; break; 
  593.  
  594. do_action( 'lib2_debug_log', 'Incoming Payment Notification for "' . $gateway . '"' ); 
  595. do_action( 'lib2_debug_log', $_POST ); 
  596.  
  597. do_action( 
  598. 'ms_gateway_handle_payment_return_' . $gateway 
  599. ); 
  600.  
  601. /** 
  602. * Show gateway credit card information. 
  603. * If a card is used, show it in account's page. 
  604. * Related action hooks: 
  605. * - ms_view_shortcode_account_card_info 
  606. * @since 1.0.0 
  607. * @param mixed $data The data passed to hooked view. 
  608. */ 
  609. public function card_info( $data = null ) { 
  610. if ( ! empty( $data['gateway'] ) && is_array( $data['gateway'] ) ) { 
  611. $gateways = array(); 
  612.  
  613. foreach ( $data['gateway'] as $ms_relationship_id => $gateway ) { 
  614. // avoid duplicates 
  615. if ( ! in_array( $gateway->id, $gateways ) ) { 
  616. $gateways[] = $gateway->id; 
  617. } else { 
  618. continue; 
  619. $view = null; 
  620.  
  621. switch ( $gateway->id ) { 
  622. case MS_Gateway_Stripe::ID: 
  623. $member = MS_Model_Member::get_current_member(); 
  624. $data['stripe'] = $member->get_gateway_profile( 
  625. $gateway->id 
  626. ); 
  627.  
  628. if ( empty( $data['stripe']['card_exp'] ) ) { 
  629. continue 2; 
  630.  
  631. $view = MS_Factory::create( 'MS_Gateway_Stripe_View_Card' ); 
  632. $data['member'] = $member; 
  633. $data['publishable_key'] = $gateway->get_publishable_key(); 
  634. $data['ms_relationship_id'] = $ms_relationship_id; 
  635. $data['gateway'] = $gateway; 
  636. break; 
  637.  
  638. case MS_Gateway_Authorize::ID: 
  639. $member = MS_Model_Member::get_current_member(); 
  640. $data['authorize'] = $member->get_gateway_profile( 
  641. $gateway->id 
  642. ); 
  643.  
  644. if ( empty( $data['authorize']['card_exp'] ) ) { 
  645. continue 2; 
  646.  
  647. $view = MS_Factory::create( 'MS_Gateway_Authorize_View_Card' ); 
  648. $data['member'] = $member; 
  649. $data['ms_relationship_id'] = $ms_relationship_id; 
  650. $data['gateway'] = $gateway; 
  651. break; 
  652.  
  653. default: 
  654. break; 
  655.  
  656. if ( ! empty( $view ) ) { 
  657. $view = apply_filters( 
  658. 'ms_gateway_view_change_card',  
  659. $view,  
  660. $gateway->id 
  661. ); 
  662. $view->data = apply_filters( 
  663. 'ms_gateway_view_change_card_data',  
  664. $data,  
  665. $gateway->id 
  666. ); 
  667.  
  668. $html = $view->to_html(); 
  669. echo '' . $html; 
  670.  
  671. /** 
  672. * Handle update credit card information in gateway. 
  673. * Used to change credit card info in account's page. 
  674. * Related action hooks: 
  675. * - template_redirect 
  676. * @since 1.0.0 
  677. */ 
  678. public function update_card() { 
  679. if ( ! empty( $_POST['gateway'] ) ) { 
  680. $gateway = MS_Model_Gateway::factory( $_POST['gateway'] ); 
  681. $member = MS_Model_Member::get_current_member(); 
  682.  
  683. switch ( $gateway->id ) { 
  684. case MS_Gateway_Stripe::ID: 
  685. if ( ! empty( $_POST['stripeToken'] ) && $this->verify_nonce() ) { 
  686. lib2()->array->strip_slashes( $_POST, 'stripeToken' ); 
  687.  
  688. $gateway->add_card( $member, $_POST['stripeToken'] ); 
  689. if ( ! empty( $_POST['ms_relationship_id'] ) ) { 
  690. $ms_relationship = MS_Factory::load( 
  691. 'MS_Model_Relationship',  
  692. $_POST['ms_relationship_id'] 
  693. ); 
  694. MS_Model_Event::save_event( 
  695. MS_Model_Event::TYPE_UPDATED_INFO,  
  696. $ms_relationship 
  697. ); 
  698.  
  699. wp_safe_redirect( 
  700. esc_url_raw( add_query_arg( array( 'msg' => 1 ) ) ) 
  701. ); 
  702. exit; 
  703. break; 
  704.  
  705. case MS_Gateway_Authorize::ID: 
  706. if ( $this->verify_nonce() ) { 
  707. do_action( 
  708. 'ms_controller_frontend_signup_gateway_form',  
  709. $this 
  710. ); 
  711. } elseif ( ! empty( $_POST['ms_relationship_id'] ) 
  712. && $this->verify_nonce( $_POST['gateway'] .'_' . $_POST['ms_relationship_id'] ) 
  713. ) { 
  714. $gateway->update_cim_profile( $member ); 
  715. $gateway->save_card_info( $member ); 
  716. if ( ! empty( $_POST['ms_relationship_id'] ) ) { 
  717. $ms_relationship = MS_Factory::load( 
  718. 'MS_Model_Relationship',  
  719. $_POST['ms_relationship_id'] 
  720. ); 
  721. MS_Model_Event::save_event( 
  722. MS_Model_Event::TYPE_UPDATED_INFO,  
  723. $ms_relationship 
  724. ); 
  725.  
  726. wp_safe_redirect( 
  727. esc_url_raw( add_query_arg( array( 'msg' => 1 ) ) ) 
  728. ); 
  729. exit; 
  730. break; 
  731.  
  732. default: 
  733. break; 
  734.  
  735. do_action( 
  736. 'ms_controller_gateway_update_card',  
  737. $this 
  738. ); 
  739.  
  740. /** 
  741. * Adds CSS and javascript 
  742. * @since 1.0.0 
  743. */ 
  744. public function enqueue_scripts( $step = null ) { 
  745. if ( empty( $step ) && ! empty( $_POST['step'] ) ) { 
  746. $step = $_POST['step']; 
  747.  
  748. lib2()->array->equip_post( 'gateway' ); 
  749. $gateway_id = $_POST['gateway']; 
  750.  
  751. switch ( $step ) { 
  752. case MS_Controller_Frontend::STEP_GATEWAY_FORM: 
  753. if ( MS_Gateway_Authorize::ID == $gateway_id ) { 
  754. wp_enqueue_script( 'jquery-validate' ); 
  755.  
  756. $data = array( 
  757. 'ms_init' => array( 'gateway_authorize' ),  
  758. ); 
  759.  
  760. lib2()->ui->data( 'ms_data', $data ); 
  761. wp_enqueue_script( 'ms-public' ); 
  762. break; 
  763.