/app/controller/class-ms-controller-import.php

  1. <?php 
  2. /** 
  3. * Class that handles Import/Export functions. 
  4. * 
  5. * @since 1.0.0 
  6. * @package Membership2 
  7. * @subpackage Controller 
  8. */ 
  9. class MS_Controller_Import extends MS_Controller { 
  10.  
  11. // Action definitions. 
  12. const ACTION_EXPORT = 'export'; 
  13. const ACTION_PREVIEW = 'preview'; 
  14.  
  15. // Ajax action: Import data. 
  16. const AJAX_ACTION_IMPORT = 'ms_import'; 
  17.  
  18. // Ajax action: Save an automatic transaction matching (Billings page). 
  19. const AJAX_ACTION_MATCH = 'ms_save_matching'; 
  20.  
  21. // Ajax action: Retry to process a single transaction (Billings page). 
  22. const AJAX_ACTION_RETRY = 'transaction_retry'; 
  23.  
  24. /** 
  25. * Prepare the Import manager. 
  26. * 
  27. * @since 1.0.0 
  28. */ 
  29. public function __construct() { 
  30. parent::__construct(); 
  31.  
  32. $this->add_ajax_action( 
  33. self::AJAX_ACTION_IMPORT,  
  34. 'ajax_action_import' 
  35. ); 
  36.  
  37. $this->add_ajax_action( 
  38. self::AJAX_ACTION_MATCH,  
  39. 'ajax_action_match' 
  40. ); 
  41.  
  42. $this->add_ajax_action( 
  43. self::AJAX_ACTION_RETRY,  
  44. 'ajax_action_retry' 
  45. ); 
  46.  
  47. /** 
  48. * Initialize the admin-side functions. 
  49. * 
  50. * @since 1.0.0 
  51. */ 
  52. public function admin_init() { 
  53. $tab_key = 'import'; // should be unique plugin-wide value of `&tab=`. 
  54.  
  55. $this->run_action( 
  56. 'ms_controller_settings_enqueue_scripts_' . $tab_key,  
  57. 'enqueue_scripts' 
  58. ); 
  59.  
  60. /** 
  61. * Handles the matching of transaction details with a membership. 
  62. * 
  63. * Expected output: 
  64. * OK:Message to display 
  65. * ERR 
  66. * 
  67. * @since 1.0.1.2 
  68. */ 
  69. public function ajax_action_match() { 
  70. $res = 'ERR'; 
  71.  
  72. if ( ! $this->is_admin_user() ) { 
  73. return; 
  74.  
  75. $fields_match = array( 'match_with', 'source', 'source_id' ); 
  76.  
  77. // Save details of a single invoice. 
  78. if ( $this->verify_nonce() 
  79. && self::validate_required( $fields_match ) 
  80. ) { 
  81. $source = $_POST['source']; 
  82. $source_id = $_POST['source_id']; 
  83. $match_id = $_POST['match_with']; 
  84.  
  85. if ( MS_Model_Import::match_with_source( $match_id, $source_id, $source ) ) { 
  86. $res = 'OK:' . __( 'Matching details saved. Future transactions are automatically processed from now on!', 'membership2' ); 
  87.  
  88. echo $res; 
  89. exit; 
  90.  
  91. /** 
  92. * Retries to process a single error-state transaction. 
  93. * 
  94. * Expected output: 
  95. * OK 
  96. * ERR 
  97. * 
  98. * @since 1.0.1.2 
  99. */ 
  100. public function ajax_action_retry() { 
  101. $res = 'ERR'; 
  102.  
  103. if ( ! $this->is_admin_user() ) { 
  104. return; 
  105.  
  106. $fields_retry = array( 'id' ); 
  107.  
  108. // Save details of a single invoice. 
  109. if ( $this->verify_nonce() 
  110. && self::validate_required( $fields_retry ) 
  111. ) { 
  112. $log_id = intval( $_POST['id'] ); 
  113.  
  114. if ( MS_Model_Import::retry_to_process( $log_id ) ) { 
  115. $res = 'OK'; 
  116.  
  117. $log = MS_Factory::load( 'MS_Model_Transactionlog', $log_id ); 
  118. $res .= ':' . $log->description; 
  119.  
  120. echo $res; 
  121. exit; 
  122.  
  123. /** 
  124. * Handles an import batch that is sent via ajax. 
  125. * 
  126. * One batch includes multiple import commands that are to be processed in 
  127. * the specified order. 
  128. * 
  129. * Expected output: 
  130. * OK:<number of successful commands> 
  131. * ERR 
  132. * 
  133. * @since 1.0.0 
  134. */ 
  135. public function ajax_action_import() { 
  136. $res = 'ERR'; 
  137. $success = 0; 
  138.  
  139. if ( ! isset( $_POST['items'] ) || ! isset( $_POST['source'] ) ) { 
  140. echo $res; 
  141. exit; 
  142.  
  143. $batch = $_POST['items']; 
  144. $source = $_POST['source']; 
  145.  
  146. $res = 'OK'; 
  147. foreach ( $batch as $item ) { 
  148. if ( $this->process_item( $item, $source ) ) { 
  149. $success += 1; 
  150.  
  151. echo $res . ':' . $success; 
  152. exit; 
  153.  
  154. /** 
  155. * Processes a single import command. 
  156. * 
  157. * @since 1.0.0 
  158. * @param array $item The import command. 
  159. */ 
  160. protected function process_item( $item, $source ) { 
  161. $res = false; 
  162.  
  163. lib3()->array->equip( $item, 'task', 'data' ); 
  164. $task = $item['task']; 
  165. $data = $item['data']; 
  166. $model = MS_Factory::create( 'MS_Model_Import' ); 
  167. $model->source_key = $source; 
  168.  
  169. // Set MS_STOP_EMAILS modifier to suppress any outgoing emails. 
  170. MS_Plugin::set_modifier( 'MS_STOP_EMAILS', true ); 
  171.  
  172. // Possible tasks are defined in ms-view-settings-import.js 
  173. switch ( $task ) { 
  174. case 'start': 
  175. lib3()->array->equip( $item, 'clear' ); 
  176. $clear = lib3()->is_true( $item['clear'] ); 
  177. $model->start( $clear ); 
  178. $res = true; 
  179. break; 
  180.  
  181. case 'import-membership': 
  182. // Function expects an object, not an array! 
  183. $data = (object) $data; 
  184. $model->import_membership( $data ); 
  185. $res = true; 
  186. break; 
  187.  
  188. case 'import-member': 
  189. // Function expects an object, not an array! 
  190. $data = (object) $data; 
  191. $model->import_member( $data ); 
  192. $res = true; 
  193. break; 
  194.  
  195. case 'import-settings': 
  196. lib3()->array->equip( $item, 'setting', 'value' ); 
  197. $setting = $item['setting']; 
  198. $value = $item['value']; 
  199. $model->import_setting( $setting, $value ); 
  200. $res = true; 
  201. break; 
  202.  
  203. case 'done': 
  204. $model->done(); 
  205. $res = true; 
  206. break; 
  207.  
  208. /** 
  209. * After the import action was complated notify other objects and 
  210. * add-ons. 
  211. * 
  212. * @since 1.0.0 
  213. */ 
  214. do_action( 'ms_import_action_' . $task, $item ); 
  215.  
  216. return $res; 
  217.  
  218. /** 
  219. * Main entry point: Processes the import/export action. 
  220. * 
  221. * This function is called by the settings-controller whenever the 
  222. * Import/Export tab provides a correct nonce. We will first find out which 
  223. * action to execute and then handle all the details... 
  224. * 
  225. * @since 1.0.0 
  226. */ 
  227. public function process() { 
  228. lib3()->array->equip_post( 'action', 'import_source' ); 
  229. $action = $_POST['action']; 
  230.  
  231. if ( isset( $_POST['submit'] ) ) { 
  232. $action = $_POST['submit']; 
  233.  
  234. switch ( $action ) { 
  235. case self::ACTION_EXPORT: 
  236. $handler = MS_Factory::create( 'MS_Model_Import_Export' ); 
  237. $handler->process(); 
  238. break; 
  239.  
  240. case self::ACTION_PREVIEW: 
  241. $view = MS_Factory::create( 'MS_View_Settings_Import' ); 
  242. $model_name = 'MS_Model_Import_' . $_POST['import_source']; 
  243. $model = null; 
  244.  
  245. try { 
  246. $model = MS_Factory::create( $model_name ); 
  247. } catch( Exception $ex ) { 
  248. self::_message( 
  249. 'error',  
  250. __( 'Coming soon: This import source is not supported yet...', 'membership2' ) 
  251. ); 
  252.  
  253. if ( is_a( $model, 'MS_Model_Import' ) ) { 
  254. if ( $model->prepare() ) { 
  255. $data = array( 
  256. 'model' => $model,  
  257. ); 
  258.  
  259. $view->data = apply_filters( 
  260. 'ms_view_import_data',  
  261. $data 
  262. ); 
  263.  
  264. self::_message( 
  265. 'preview',  
  266. apply_filters( 
  267. 'ms_view_import_preview',  
  268. $view->to_html() 
  269. ); 
  270. break; 
  271.  
  272. /** 
  273. * Enqueue admin scripts in the settings screen. 
  274. * 
  275. * @since 1.0.0 
  276. */ 
  277. public function enqueue_scripts() { 
  278. $data = array( 
  279. 'ms_init' => array( 'view_settings_import' ),  
  280. 'lang' => array( 
  281. 'progress_title' => __( 'Importing data...', 'membership2' ),  
  282. 'close_progress' => __( 'Okay', 'membership2' ),  
  283. 'import_done' => __( 'All done!', 'membership2' ),  
  284. 'task_start' => __( 'Preparing...', 'membership2' ),  
  285. 'task_done' => __( 'Cleaning up...', 'membership2' ),  
  286. 'task_import_member' => __( 'Importing Member', 'membership2' ),  
  287. 'task_import_membership' => __( 'Importing Membership', 'membership2' ),  
  288. 'task_import_settings' => __( 'Importing Settings', 'membership2' ),  
  289. ),  
  290. ); 
  291.  
  292. lib3()->ui->data( 'ms_data', $data ); 
  293. wp_enqueue_script( 'ms-admin' ); 
  294.  
.