WJ_Export

Class Export.

Defined (1)

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

/classes/WJ_Export.php  
  1. class WJ_Export extends WYSIJA_object { 
  2.  
  3. private $_file_header = ''; 
  4. private $_file_handle = null; 
  5. private $_user_ids_rows = 0; 
  6. private $_user_ids = array(); 
  7. private $_fields = array(); 
  8. private $_export_batch = 2000; 
  9. private $_filter_list = ''; 
  10. private $_filter_confirmed = ''; 
  11. private $_fields_separator = ';'; 
  12. private $_lines_separator = "\n"; 
  13. private $_base_encode = 'UTF-8'; 
  14. /** 
  15. * Default encoding of exported files 
  16. * @var string 
  17. */ 
  18. private $_output_encode = 'UTF-8//TRANSLIT//IGNORE'; 
  19.  
  20. //needed for tung's batch actions 
  21. public $batch_select = null; 
  22.  
  23. function __construct() { 
  24. if ( ! empty( $_POST['wysija']['export']['fields'] ) ) { 
  25. $this->_fields = $_POST['wysija']['export']['fields']; 
  26.  
  27. if ( ! empty( $_POST['wysija']['export']['user_ids'] ) ) { 
  28. $this->_user_ids = $this->_get_posted_user_ids(); 
  29. if ( ! empty($_POST['wysija']['export']['filter']['list'] ) ) { 
  30. $this->_filter_list = $_POST['wysija']['export']['filter']['list']; 
  31.  
  32. // how do we separate the values in the files commas or semy colons ? 
  33. if ( ! empty($_POST['wysija']['export']['format'] ) ) { 
  34. $this->_fields_separator = $_POST['wysija']['export']['format']; 
  35.  
  36. if ( ! empty($_POST['wysija']['export']['filter']['confirmed'] ) ) { 
  37. $this->_filter_confirmed = $_POST['wysija']['export']['filter']['confirmed']; 
  38.  
  39. $this->set_output_encode(); 
  40.  
  41. /** 
  42. * Set output encoding based on platform 
  43. */ 
  44. protected function set_output_encode() { 
  45. $this->_output_encode = WYSIJA::is_windows() ? 'Windows-1252' : 'UTF-8//TRANSLIT//IGNORE'; 
  46.  
  47. /** 
  48. * get the number of rows exported 
  49. * @return type 
  50. */ 
  51. public function get_user_ids_rows() { 
  52. return $this->_user_ids_rows; 
  53.  
  54. /** 
  55. * get an array of user_ids from the global $_POST 
  56. * @return type 
  57. */ 
  58. private function _get_posted_user_ids() { 
  59. return (array) json_decode( base64_decode( $_POST['wysija']['export']['user_ids'] ), true ); 
  60.  
  61. /** 
  62. * get the query used to select a bung of ids 
  63. * @return string 
  64. */ 
  65. private function _get_query_users_ids() { 
  66.  
  67. // based on filters prepare a query to get a list of user_ids 
  68. if ( ! empty( $this->batch_select ) ) { // batch select and export 
  69. $this->_user_ids_rows = $this->batch_select['count']; 
  70. $qry = $this->batch_select['original_query']; 
  71. } else { // export all list 
  72. // prepare the filters 
  73. $filters = array(); 
  74. if ( ! empty( $this->_filter_list ) ) { 
  75. if ( ! is_array( $this->_filter_list ) ) { 
  76. $this->_filter_list = array( $this->_filter_list ); 
  77. $filters['lists'] = $this->_filter_list; 
  78.  
  79. // include also unsubscribed and unconfirmed 
  80. if ( ! empty( $this->_filter_confirmed ) ) { 
  81. $filters['status'] = 'subscribed'; 
  82.  
  83. $model_user = WYSIJA::get( 'user', 'model' ); 
  84. $select = array( 'A.user_id' ); 
  85. $qry = $model_user->get_subscribers( $select, $filters, '', $return_query = true ); 
  86.  
  87. return $qry; 
  88.  
  89. /** 
  90. * get chunks of subscribers ids and push them step by step to the export file 
  91. */ 
  92. private function _get_chunks_user_ids() { 
  93.  
  94. $model_user = WYSIJA::get( 'user', 'model' ); 
  95. $this->_user_ids = array(); 
  96. $query_user_ids = $this->_get_query_users_ids(); 
  97. $query_count = str_replace( array( 'DISTINCT(A.user_id)', 'DISTINCT(B.user_id)' ), 'COUNT(DISTINCT(A.user_id))', $query_user_ids ); 
  98.  
  99. if ( empty( $this->_user_ids_rows ) ) { 
  100. $useridsrows_result = $model_user->getResults( $query_count, ARRAY_N ); 
  101. $this->_user_ids_rows = (int) $useridsrows_result[0][0]; 
  102.  
  103. if ( $this->_user_ids_rows <= $this->_export_batch ) { 
  104. $user_ids_db = $model_user->getResults( $query_user_ids, ARRAY_N ); 
  105.  
  106. foreach ( $user_ids_db as $uarr ) { 
  107. $this->_user_ids[] = $uarr[0]; 
  108.  
  109. $this->_push_data_to_export_file(); 
  110. } else { 
  111. $pages = ceil( $this->_user_ids_rows / $this->_export_batch ); //pagination 
  112. for ( $i = 0; $i < $pages; $i++ ) { 
  113. $query_batch = $query_user_ids . ' ORDER BY user_id ASC LIMIT ' . ($i * $this->_export_batch) . ', ' . $this->_export_batch; 
  114. $user_ids_db = $model_user->getResults( $query_batch, ARRAY_N ); 
  115. foreach ( $user_ids_db as $uarr ) { 
  116. $this->_user_ids[] = $uarr[0]; 
  117. $this->_push_data_to_export_file(); 
  118.  
  119. unset($user_ids_db); //free memory 
  120.  
  121. /** 
  122. * split the user_ids array into chunks, load the fields of all the concerned 
  123. * users and push the data to the file 
  124. */ 
  125. private function _push_data_to_export_file() { 
  126. $user_ids_chunks = array(); // chunk rows into separated batchs, limit by $this->_export_batch 
  127. $user_ids_chunks = array_chunk( $this->_user_ids, 200 ); 
  128. $this->_user_ids = null; // free memory 
  129.  
  130. $model_user = WYSIJA::get( 'user', 'model' ); 
  131. $model_user->refresh_columns(); 
  132. foreach ( $user_ids_chunks as $user_id_chunk ) { 
  133. // get the full data for that specific chunk of ids 
  134. $data = $model_user->get( $this->_fields, array( 'user_id' => $user_id_chunk ) ); 
  135.  
  136. if ( in_array( 'created_at', $this->_fields ) ) { 
  137. foreach ( $data as $key => $row ) { 
  138. $data[$key]['created_at'] = date_i18n( get_option( 'date_format' ), $row['created_at'] ); 
  139.  
  140. $rows_count = count( $data ); 
  141.  
  142. // As required in Wysija/plugin#798 removed BOM from file 
  143. // fwrite( $this->_file_handle, "\xEF\xBB\xBF" ); 
  144.  
  145. // append content to the file 
  146. foreach ( $data as $k => $row ) { 
  147. $row = array_map(function($value) { 
  148. $value = str_replace('"', '""', $value); 
  149. return (preg_match('/, /', $value)) ? 
  150. '"' . $value . '"' : 
  151. $value; 
  152. }, $row); 
  153. $row_string = implode( $this->_fields_separator, $row ); 
  154. $encoded_string = iconv( $this->_base_encode, $this->_output_encode, $row_string ); 
  155. fwrite( $this->_file_handle, $encoded_string . ( $rows_count !== $k ? $this->_lines_separator : '' ) ); 
  156.  
  157. /** 
  158. * simply prepare the header of the file based on the fields 
  159. */ 
  160. private function _prepare_headers() { 
  161. $model_user = WYSIJA::get( 'user_field', 'model' ); 
  162. $database_fields = $model_user->getFields(); 
  163.  
  164. $name_fields = array(); 
  165. //prepare the columns that need to be exported 
  166. foreach ( $this->_fields as $key_field ) { 
  167. $name_fields[] = $database_fields[$key_field]; 
  168.  
  169. //create the export file step by step 
  170. $row_string = implode( $this->_fields_separator, $name_fields ) . $this->_lines_separator; 
  171. $encoded_string = iconv( $this->_base_encode, $this->_output_encode, $row_string ); 
  172. $this->_file_header = $encoded_string; 
  173.  
  174. /** 
  175. * export the subscribers 
  176. * @return type 
  177. */ 
  178. public function export_subscribers() { 
  179.  
  180. //generate temp file 
  181. $helper_file = WYSIJA::get( 'file', 'helper' ); 
  182. $this->_prepare_headers(); 
  183. $result_file = $helper_file->temp( $this->_file_header, 'export', '.csv' ); 
  184.  
  185. //open the created file in append mode 
  186. $this->_file_handle = fopen( $result_file['path'], 'a' ); 
  187.  
  188. //get a list of user_ids to export 
  189. if ( ! empty( $this->_user_ids ) && empty( $this->batch_select ) ) { 
  190.  
  191. $this->_user_ids_rows = count( $this->_user_ids ); 
  192. $this->_push_data_to_export_file(); 
  193. } else { 
  194.  
  195. $this->_get_chunks_user_ids(); 
  196.  
  197. fclose( $this->_file_handle ); 
  198. return $result_file; 
  199.