Completed
Pull Request — master (#1832)
by Devin
04:50
created

Give_Batch_Export::pre_fetch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 24 and the first side effect is on line 16.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Batch Export Class
4
 *
5
 * This is the base class for all batch export methods. Each data export type (donors, payments, etc) extend this class.
6
 *
7
 * @package     Give
8
 * @subpackage  Admin/Export
9
 * @copyright   Copyright (c) 2016, WordImpress
10
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
11
 * @since       1.5
12
 */
13
14
// Exit if accessed directly.
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
/**
20
 * Give_Batch_Export Class
21
 *
22
 * @since 1.5
23
 */
24
class Give_Batch_Export extends Give_Export {
25
26
	/**
27
	 * The file the data is stored in.
28
	 *
29
	 * @since 1.5
30
	 */
31
	private $file;
32
33
	/**
34
	 * The name of the file the data is stored in.
35
	 *
36
	 * @since 1.5
37
	 */
38
	public $filename;
39
40
	/**
41
	 * The file type, typically .csv
42
	 *
43
	 * @since 1.5
44
	 */
45
	public $filetype;
46
47
	/**
48
	 * The current step being processed.
49
	 *
50
	 * @since 1.5
51
	 */
52
	public $step;
53
54
	/**
55
	 * Start date, Y-m-d H:i:s
56
	 *
57
	 * @since 1.5
58
	 */
59
	public $start;
60
61
	/**
62
	 * End date, Y-m-d H:i:s
63
	 *
64
	 * @since 1.5
65
	 */
66
	public $end;
67
68
	/**
69
	 * Status to export.
70
	 *
71
	 * @since 1.5
72
	 */
73
	public $status;
74
75
	/**
76
	 * Form to export data for.
77
	 *
78
	 * @since 1.5
79
	 */
80
	public $form = null;
81
82
	/**
83
	 * Form Price ID to export data for.
84
	 *
85
	 * @since 1.5
86
	 */
87
	public $price_id = null;
88
89
	/**
90
	 * Is the export file writable.
91
	 *
92
	 * @since 1.5
93
	 */
94
	public $is_writable = true;
95
96
	/**
97
	 *  Is the export file empty.
98
	 *
99
	 * @since 1.5
100
	 */
101
	public $is_empty = false;
102
103
	/**
104
	 *
105
	 * @since 1.8.9
106
	 */
107
	public $is_void = false;
108
109
	/**
110
	 *  Is the export file complete.
111
	 *
112
	 * @since 1.8.9
113
	 */
114
	public $done = false;
115
116
	/**
117
	 * Give_Batch_Export constructor.
118
	 *
119
	 * @param int $_step
120
	 */
121
	public function __construct( $_step = 1 ) {
122
123
		$upload_dir     = wp_upload_dir();
124
		$this->filetype = '.csv';
125
		$this->filename = 'give-' . $this->export_type . $this->filetype;
126
		$this->file     = trailingslashit( $upload_dir['basedir'] ) . $this->filename;
127
128
		if ( ! is_writeable( $upload_dir['basedir'] ) ) {
129
			$this->is_writable = false;
130
		}
131
132
		$this->step = $_step;
133
		$this->done = false;
134
	}
135
136
	/**
137
	 * Process a step.
138
	 *
139
	 * @since 1.5
140
	 * @return bool
141
	 */
142
	public function process_step() {
143
144
		if ( ! $this->can_export() ) {
145
			wp_die( esc_html__( 'You do not have permission to export data.', 'give' ), esc_html__( 'Error', 'give' ), array(
146
				'response' => 403,
147
			) );
148
		}
149
150
		if ( $this->step < 2 ) {
151
152
			// Make sure we start with a fresh file on step 1.
153
			@unlink( $this->file );
154
			$this->print_csv_cols();
155
		}
156
157
		$rows = $this->print_csv_rows();
158
159
		if ( $rows ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $rows of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
160
			return true;
161
		} else {
162
			return false;
163
		}
164
	}
165
166
	/**
167
	 * Output the CSV columns.
168
	 *
169
	 * @access public
170
	 * @since  1.5
171
	 * @uses   Give_Export::get_csv_cols()
172
	 * @return string
173
	 */
174
	public function print_csv_cols() {
175
176
		$col_data = '';
177
		$cols     = $this->get_csv_cols();
178
		$i        = 1;
179
		foreach ( $cols as $col_id => $column ) {
180
			$col_data .= '"' . addslashes( $column ) . '"';
181
			$col_data .= $i == count( $cols ) ? '' : ',';
182
			$i ++;
183
		}
184
		$col_data .= "\r\n";
185
186
		$this->stash_step_data( $col_data );
187
188
		return $col_data;
189
190
	}
191
192
	/**
193
	 * Print the CSV rows for the current step.
194
	 *
195
	 * @access public
196
	 * @since  1.5
197
	 * @return string|false
198
	 */
199
	public function print_csv_rows() {
200
201
		$row_data = '';
202
		$data     = $this->get_data();
203
		$cols     = $this->get_csv_cols();
204
205
		if ( $data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
206
207
			// Output each row
208
			foreach ( $data as $row ) {
209
				$i = 1;
210
				foreach ( $row as $col_id => $column ) {
211
					// Make sure the column is valid
212
					if ( array_key_exists( $col_id, $cols ) ) {
213
						$row_data .= '"' . addslashes( preg_replace( '/"/', "'", $column ) ) . '"';
214
						$row_data .= $i == count( $cols ) ? '' : ',';
215
						$i ++;
216
					}
217
				}
218
				$row_data .= "\r\n";
219
			}
220
221
			$this->stash_step_data( $row_data );
222
223
			return $row_data;
224
		}
225
226
		return false;
227
	}
228
229
	/**
230
	 * Return the calculated completion percentage.
231
	 *
232
	 * @since 1.5
233
	 * @return int
234
	 */
235
	public function get_percentage_complete() {
236
		return 100;
237
	}
238
239
	/**
240
	 * Retrieve the file data is written to.
241
	 *
242
	 * @since 1.5
243
	 * @return string
244
	 */
245
	protected function get_file() {
246
247
		$file = '';
248
249
		if ( @file_exists( $this->file ) ) {
250
251
			if ( ! is_writeable( $this->file ) ) {
252
				$this->is_writable = false;
253
			}
254
255
			$file = @file_get_contents( $this->file );
256
257
		} else {
258
259
			@file_put_contents( $this->file, '' );
260
			@chmod( $this->file, 0664 );
261
262
		}
263
264
		return $file;
265
	}
266
267
	/**
268
	 * Append data to export file.
269
	 *
270
	 * @since 1.5
271
	 *
272
	 * @param $data string The data to add to the file.
273
	 *
274
	 * @return void
275
	 */
276
	protected function stash_step_data( $data = '' ) {
277
278
		$file = $this->get_file();
279
		$file .= $data;
280
		@file_put_contents( $this->file, $file );
281
282
		// If we have no rows after this step, mark it as an empty export.
283
		$file_rows    = file( $this->file, FILE_SKIP_EMPTY_LINES );
284
		$default_cols = $this->get_csv_cols();
285
		$default_cols = empty( $default_cols ) ? 0 : 1;
286
287
		$this->is_empty = count( $file_rows ) == $default_cols ? true : false;
288
289
	}
290
291
	/**
292
	 * Perform the export.
293
	 *
294
	 * @access public
295
	 * @since  1.5
296
	 * @return void
297
	 */
298
	public function export() {
299
300
		// Set headers
301
		$this->headers();
302
303
		$file = $this->get_file();
304
305
		@unlink( $this->file );
306
307
		echo $file;
308
309
		/**
310
		 * Fire action after file output.
311
		 *
312
		 * @since 1.8
313
		 */
314
		do_action( 'give_file_export_complete', $_REQUEST );
315
316
		give_die();
317
	}
318
319
	/**
320
	 * Set the properties specific to the export.
321
	 *
322
	 * @since 1.5
323
	 *
324
	 * @param array $request The Form Data passed into the batch processing.
325
	 */
326
	public function set_properties( $request ) {
327
	}
328
329
	/**
330
	 * Unset the properties specific to the export.
331
	 *
332
	 * @since 1.8.9
333
	 *
334
	 * @param array             $request The Form Data passed into the batch processing.
335
	 * @param Give_Batch_Export $export
336
	 */
337
	public function unset_properties( $request, $export ) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
338
	}
339
340
	/**
341
	 * Allow for pre-fetching of data for the remainder of the exporter.
342
	 *
343
	 * @access public
344
	 * @since  1.5
345
	 * @return void
346
	 */
347
	public function pre_fetch() {
348
	}
349
350
}
351