MS_Helper_ListTable_TransactionMatching

List unmatched M1 sub_ids and external payment options with membership_ids.

Defined (1)

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

/app/helper/listtable/class-ms-helper-listtable-transactionmatching.php  
  1. class MS_Helper_ListTable_TransactionMatching extends MS_Helper_ListTable { 
  2.  
  3. /** 
  4. * This ID is used as class-name for the list output and also in various 
  5. * filter names in MS_Helper_ListTable. 
  6. * @var string 
  7. */ 
  8. protected $id = 'transaction_matching'; 
  9.  
  10. /** 
  11. * Currently selected matching source; 
  12. * Supported types are 
  13. * m1 .. Imported from M1 
  14. * pay_btn .. Custom PayPal Payment Button 
  15. * @var string 
  16. */ 
  17. protected $source = false; 
  18.  
  19. /** 
  20. * Currently selected source_id that should be matched. 
  21. * @var mixed 
  22. */ 
  23. protected $source_id = false; 
  24.  
  25. /** 
  26. * Constructor, defines general list table attributes. 
  27. * @since 1.0.1.2 
  28. */ 
  29. public function __construct() { 
  30. // 'singular' just added for fun... 
  31. // 'plural' is used as class name for the list. 
  32. parent::__construct( 
  33. array( 
  34. 'singular' => 'transaction_match',  
  35. 'plural' => 'transaction_matches',  
  36. ); 
  37.  
  38. /** 
  39. * Defines the columns of the list table 
  40. * @since 1.0.1.2 
  41. * @return array 
  42. */ 
  43. public function get_columns() { 
  44. $currency = MS_Plugin::instance()->settings->currency; 
  45.  
  46. $columns = apply_filters( 
  47. 'ms_helper_listtable_transactionmatching_columns',  
  48. array( 
  49. 'id' => __( 'ID', 'membership2' ),  
  50. 'date' => __( 'Time', 'membership2' ),  
  51. 'status' => '',  
  52. 'method' => '',  
  53. 'gateway' => __( 'Gateway', 'membership2' ),  
  54. 'amount' => __( 'Amount', 'membership2' ),  
  55. 'invoice' => __( 'Invoice', 'membership2' ),  
  56. 'note' => __( 'Details', 'membership2' ),  
  57. ); 
  58.  
  59. $columns = apply_filters( 
  60. 'ms_helper_listtable_transactionmatching_get_columns',  
  61. $columns,  
  62. $currency 
  63. ); 
  64.  
  65. return $columns; 
  66.  
  67. /** 
  68. * Defines, which columns should be output as hidden columns. 
  69. * @since 1.0.1.2 
  70. * @return array 
  71. */ 
  72. public function get_hidden_columns() { 
  73. return apply_filters( 
  74. 'ms_helper_listtable_transactionmatching_hidden_columns',  
  75. array() 
  76. ); 
  77.  
  78. /** 
  79. * Defines, which columns can be sorted. 
  80. * @since 1.0.1.2 
  81. * @return array 
  82. */ 
  83. public function get_sortable_columns() { 
  84. return apply_filters( 
  85. 'ms_helper_listtable_transactionmatching_sortable_columns',  
  86. array() 
  87. ); 
  88.  
  89. /** 
  90. * Defines available bulk actions. 
  91. * @since 1.0.1.2 
  92. * @return array 
  93. */ 
  94. public function get_bulk_actions() { 
  95. return apply_filters( 
  96. 'ms_helper_listtable_transactionmatching_bulk_actions',  
  97. array() 
  98. ); 
  99.  
  100. /** 
  101. * Loads the items that are displayed on the current list page. 
  102. * @since 1.0.1.2 
  103. */ 
  104. public function prepare_items() { 
  105. $this->_column_headers = array( 
  106. $this->get_columns(),  
  107. $this->get_hidden_columns(),  
  108. $this->get_sortable_columns(),  
  109. ); 
  110.  
  111. $current_page = $this->get_pagenum(); 
  112.  
  113. $args = array( 
  114. 'posts_per_page' => -1,  
  115. 'offset' => 0,  
  116. ); 
  117.  
  118. if ( ! empty( $_GET['source'] ) && ! empty( $_GET['source_id'] ) ) { 
  119. $this->source = $_GET['source']; 
  120. $this->source_id = $_GET['source_id']; 
  121.  
  122. $args['state'] = 'err'; 
  123. $args['source'] = array( $this->source_id, $this->source ); 
  124.  
  125. $total_items = MS_Model_Transactionlog::get_item_count( $args ); 
  126.  
  127. $this->items = apply_filters( 
  128. 'ms_helper_listtable_transactionmatching_items',  
  129. MS_Model_Transactionlog::get_items( $args ) 
  130. ); 
  131.  
  132. $this->set_pagination_args( 
  133. array( 
  134. 'total_items' => $total_items,  
  135. 'per_page' => $per_page,  
  136. ); 
  137.  
  138. /** 
  139. * Displays a custom search box for this list. 
  140. * @since 1.0.1.2 
  141. */ 
  142. public function search_box( $text = null, $input_id = 'search' ) { 
  143. // Do not display anything. 
  144. // Transaction logs cannot be searched currently 
  145.  
  146. /** 
  147. * Return true if the current list is a view except "all" 
  148. * In this list the function always returns true to force the filters to 
  149. * be displayed. 
  150. * @since 1.0.0 
  151. * @return bool 
  152. */ 
  153. public function is_view() { 
  154. return true; 
  155.  
  156. /** 
  157. * Returns a human readable description of the import source. 
  158. * @since 1.0.0 
  159. * @param string $source The import source. 
  160. * @param mixed $source_id The original ID. 
  161. * @return string The label. 
  162. */ 
  163. protected function get_source_label( $source, $source_id ) { 
  164. $label = __( 'Unknown ID: %s', 'membership2' ); 
  165.  
  166. switch ( $source ) { 
  167. case 'pay_btn': 
  168. $label = __( 'PayPal Payment Button #%s', 'membership2' ); 
  169. break; 
  170.  
  171. case 'm1': 
  172. default: 
  173. $label = __( 'M1 Subscription Level #%s', 'membership2' ); 
  174. break; 
  175.  
  176. $label = sprintf( $label, $source_id ); 
  177.  
  178. return $label; 
  179.  
  180. /** 
  181. * Defines predefines filters for this list table. 
  182. * Filters display the unmatched source_id values. 
  183. * @since 1.0.1.2 
  184. * @return array 
  185. */ 
  186. public function get_views() { 
  187. $views = array(); 
  188.  
  189. if ( MS_Model_Import::can_match() ) { 
  190. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  191. $lst = $settings->get_custom_setting( 'import_match' ); 
  192. if ( ! is_array( $lst ) ) { 
  193. $lst = array(); 
  194.  
  195. $views['label'] = array( 
  196. 'label' => __( 'Undefined transactions:', 'membership2' ),  
  197. ); 
  198.  
  199. foreach ( $lst as $source => $ids ) { 
  200. foreach ( $ids as $source_id ) { 
  201. $key = $source . '_' . $source_id; 
  202. $label = $this->get_source_label( $source, $source_id ); 
  203.  
  204. $views[$key] = array( 
  205. 'label' => $label,  
  206. 'url' => add_query_arg( 
  207. array( 'source' => $source, 'source_id' => $source_id ) 
  208. ),  
  209. ); 
  210.  
  211. return apply_filters( 
  212. 'ms_helper_listtable_transactionmatching_views',  
  213. $views 
  214. ); 
  215.  
  216. /** 
  217. * Display custom text after the view-links are rendered. 
  218. * @since 1.0.1.2 
  219. */ 
  220. public function views() { 
  221. parent::views(); 
  222.  
  223. if ( ! $this->source || ! $this->source_id ) { 
  224. if ( ! MS_Model_Import::can_match() ) { 
  225. $url = MS_Controller_Plugin::get_admin_url( 
  226. 'billing',  
  227. array( 'show' => 'logs' ) 
  228. ); 
  229.  
  230. echo '<p>'; 
  231. _e( 'No suitable transaction found.', 'membership2' ); 
  232. echo '</p><p>'; 
  233. printf( 
  234. '<strong>%s</strong><br />',  
  235. __( 'Nothing to do right now:', 'membership2' ) 
  236. ); 
  237. _e( 'Transactions that can be automatically matched will appear here when they are processed by a payment gateway.<br>So simply check again later after new payments were made.', 'membership2' ); 
  238. echo '</p><p>'; 
  239. printf( 
  240. __( 'If you are impatient then "Retry" some error-state transactions in the %sTransaction Logs%s section and then see if they appear on this page.', 'membership2' ),  
  241. '<a href="' . $url . '">',  
  242. '</a>' 
  243. ); 
  244. echo '</p>'; 
  245.  
  246. // Don't display anything if no matching source was selected. 
  247. return; 
  248.  
  249. if ( ! MS_Model_Import::can_match( $this->source_id, $this->source ) ) { 
  250. // For this transaction details is no matching possible right now. 
  251. return; 
  252.  
  253. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  254. $label = $this->get_source_label( $this->source, $this->source_id ); 
  255. $memberships = MS_Model_Membership::get_memberships(); 
  256.  
  257. $options = array( '0' => '-----' ); 
  258. foreach ( $memberships as $item ) { 
  259. if ( $item->is_system() ) { continue; } 
  260. if ( 'm1' == $this->source ) { 
  261. // Only one membership can be matched with a M1 sub_id. 
  262. if ( $item->source_id ) { continue; } 
  263.  
  264. if ( $item->is_free() ) { 
  265. $options[$item->id] = sprintf( 
  266. '%s • %s',  
  267. $item->name,  
  268. __( 'Free', 'membership2' ) 
  269. ); 
  270. } else { 
  271. $options[$item->id] = sprintf( 
  272. '%s • %s • %s',  
  273. $item->name,  
  274. $settings->currency . ' ' . MS_Helper_Billing::format_price( $item->price ),  
  275. $item->get_payment_type_desc() 
  276. ); 
  277.  
  278. asort( $options ); 
  279.  
  280. $field_memberships = array( 
  281. 'id' => 'match_with',  
  282. 'type' => MS_Helper_Html::INPUT_TYPE_SELECT,  
  283. 'before' => sprintf( 
  284. __( '2. Link %s with', 'membership2' ),  
  285. '<b>' . $label . '</b>' 
  286. ),  
  287. 'field_options' => $options,  
  288. ); 
  289. $field_action = array( 
  290. 'id' => 'action',  
  291. 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN,  
  292. 'value' => MS_Controller_Import::AJAX_ACTION_MATCH,  
  293. ); 
  294. $field_source = array( 
  295. 'id' => 'source',  
  296. 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN,  
  297. 'value' => $this->source,  
  298. ); 
  299. $field_source_id = array( 
  300. 'id' => 'source_id',  
  301. 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN,  
  302. 'value' => $this->source_id,  
  303. ); 
  304. $field_save = array( 
  305. 'class' => 'action-match',  
  306. 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT,  
  307. 'value' => __( 'Save', 'membership2' ),  
  308. ); 
  309. $field_retry_action = array( 
  310. 'class' => 'retry_action',  
  311. 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN,  
  312. 'value' => MS_Controller_Import::AJAX_ACTION_RETRY,  
  313. ); 
  314. $field_retry_nonce = array( 
  315. 'class' => 'retry_nonce',  
  316. 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN,  
  317. 'value' => wp_create_nonce( MS_Controller_Import::AJAX_ACTION_RETRY ),  
  318. ); 
  319.  
  320. ?> 
  321. <div class="cf"></div> 
  322. <form class="transaction-matching"> 
  323. <?php 
  324. wp_nonce_field( MS_Controller_Import::AJAX_ACTION_MATCH ); 
  325. MS_Helper_Html::html_element( $field_retry_action ); 
  326. MS_Helper_Html::html_element( $field_retry_nonce ); 
  327. MS_Helper_Html::html_element( $field_action ); 
  328. MS_Helper_Html::html_element( $field_source ); 
  329. MS_Helper_Html::html_element( $field_source_id ); 
  330. ?> 
  331. <div class="content"> 
  332. <p><?php 
  333. printf( 
  334. __( '1. Below is a list of past "%s" transactions. Examine these transactions to find out which Membership they refer to.', 'membership2' ),  
  335. '<b>' . $label . '</b>' 
  336. ); 
  337. ?></p> 
  338. <hr /> 
  339. <p><?php 
  340. MS_Helper_Html::html_element( $field_memberships ); 
  341. ?></p> 
  342. <div style="margin-left:14px"> 
  343. <?php 
  344. _e( 'Notes:', 'membership2' ); 
  345. ?> 
  346. <br /> 
  347. <?php 
  348. _e( 'This choice is saved so new transactions are processed automatically from now on.', 'membership2' ); 
  349. ?> 
  350. <br /> 
  351. <?php 
  352. _e( 'Upon saving all transactions below will be processed, this might take a while.', 'membership2' ); 
  353. ?> 
  354. </div> 
  355. </div> 
  356. <div class="buttons"> 
  357. <?php MS_Helper_Html::html_element( $field_save ); ?> 
  358. </div> 
  359. </form> 
  360. <?php 
  361.  
  362. /** 
  363. * Custom display function to hide item table for invalid filter options. 
  364. * @since 1.0.1.2 
  365. */ 
  366. public function display() { 
  367. if ( MS_Model_Import::can_match( $this->source_id, $this->source ) ) { 
  368. parent::display(); 
  369.  
  370. /** 
  371. * Returns the row-class to be used for the specified table item. 
  372. * @param object $item The current item. 
  373. * @return string Class to be added to the table row. 
  374. */ 
  375. protected function single_row_class( $item ) { 
  376. $class = 'log-' . $item->state; 
  377.  
  378. if ( $item->is_manual ) { 
  379. $class .= ' is-manual'; 
  380.  
  381. return $class; 
  382.  
  383. /** 
  384. * Output column content 
  385. * @since 1.0.1.2 
  386. * @param object $item The item that is displayed. 
  387. * @return string The HTML code to output. 
  388. */ 
  389. public function column_id( $item, $column_name ) { 
  390. $html = $item->id; 
  391. return $html; 
  392.  
  393. /** 
  394. * Output column content 
  395. * @since 1.0.1.2 
  396. * @param object $item The item that is displayed. 
  397. * @return string The HTML code to output. 
  398. */ 
  399. public function column_date( $item, $column_name ) { 
  400. $html = MS_Helper_Period::format_date( $item->date, 'Y-m-d H:i' ); 
  401.  
  402. return $html; 
  403.  
  404. /** 
  405. * Output column content 
  406. * @since 1.0.1.2 
  407. * @param object $item The item that is displayed. 
  408. * @return string The HTML code to output. 
  409. */ 
  410. public function column_status( $item, $column_name ) { 
  411. $html = '<span class="log-status"><i class="wpmui-fa log-status-icon"></i></span>'; 
  412.  
  413. return $html; 
  414.  
  415. /** 
  416. * Output column content 
  417. * @since 1.0.1.2 
  418. * @param object $item The item that is displayed. 
  419. * @return string The HTML code to output. 
  420. */ 
  421. public function column_method( $item, $column_name ) { 
  422. $html = '<span class="log-method" data-info="%2$s"><i class="wpmui-fa wpmui-%1$s"></i></span>'; 
  423. $icon = ''; 
  424. $info = __( 'Unknown method', 'membership2' ); 
  425.  
  426. switch ( $item->method ) { 
  427. case 'handle': 
  428. $icon = 'fa-cloud-download'; 
  429. $info = __( 'Gateway called the IPN URL', 'membership2' ); 
  430. break; 
  431.  
  432. case 'request': 
  433. $icon = 'fa-refresh'; 
  434. $info = __( 'Plugin requested a recuring payment', 'membership2' ); 
  435. break; 
  436.  
  437. case 'process': 
  438. $icon = 'fa-shopping-cart'; 
  439. $info = __( 'User entered payment details', 'membership2' ); 
  440. break; 
  441.  
  442. $html = sprintf( $html, $icon, $info ); 
  443.  
  444. return $html; 
  445.  
  446. /** 
  447. * Output column content 
  448. * @since 1.0.1.2 
  449. * @param object $item The item that is displayed. 
  450. * @return string The HTML code to output. 
  451. */ 
  452. public function column_gateway( $item, $column_name ) { 
  453. $html = MS_Model_Gateway::get_name( $item->gateway_id, true ); 
  454. return $html; 
  455.  
  456. /** 
  457. * Output column content 
  458. * @since 1.0.1.2 
  459. * @param object $item The item that is displayed. 
  460. * @return string The HTML code to output. 
  461. */ 
  462. public function column_amount( $item, $column_name ) { 
  463. $html = MS_Helper_Billing::format_price( $item->amount ); 
  464.  
  465. return $html; 
  466.  
  467. /** 
  468. * Output column content 
  469. * @since 1.0.1.2 
  470. * @param object $item The item that is displayed. 
  471. * @return string The HTML code to output. 
  472. */ 
  473. public function column_invoice( $item, $column_name ) { 
  474. if ( $item->invoice_id ) { 
  475. $invoice_url = MS_Controller_Plugin::get_admin_url( 
  476. 'billing',  
  477. array( 'action' => 'edit', 'invoice_id' => $item->invoice_id ) 
  478. ); 
  479.  
  480. $html = sprintf( 
  481. '<a href="%1$s">%2$s</a>',  
  482. $invoice_url,  
  483. $item->invoice_id 
  484. ); 
  485. } else { 
  486. $html = '-'; 
  487.  
  488. return $html; 
  489.  
  490. /** 
  491. * Output column content 
  492. * @since 1.0.1.2 
  493. * @param object $item The item that is displayed. 
  494. * @return string The HTML code to output. 
  495. */ 
  496. public function column_note( $item, $column_name ) { 
  497. $extra_infos = ''; 
  498. $detail_lines = array(); 
  499.  
  500. // 1. Prepare the "Additional Details" popup. 
  501. $detail_lines = MS_Helper_ListTable_TransactionLog::get_details( $item ); 
  502.  
  503. if ( count( $detail_lines ) ) { 
  504. $icon_class = ''; 
  505. $post_data = $item->post; 
  506. if ( ! $post_data ) { 
  507. $icon_class = 'no-post'; 
  508.  
  509. $extra_infos = sprintf( 
  510. '<div class="more-details %3$s">%2$s<div class="post-data"><div class="inner">%1$s</div></div></div>',  
  511. implode( '<br>', $detail_lines ),  
  512. '<i class="wpmui-fa wpmui-fa-info-circle"></i>',  
  513. $icon_class 
  514. ); 
  515.  
  516. // 2. Combine the prepared parts. 
  517. $html = sprintf( 
  518. '<div class="detail-block">%s <span class="txt">%s</span></div>',  
  519. $extra_infos,  
  520. $item->description 
  521. ); 
  522.  
  523. return $html; 
  524.