Completed
Push — master ( 15aa29...17da96 )
by Claudio
18:39 queued 11s
created

includes/export/abstract-wc-csv-batch-exporter.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Handles Batch CSV export.
4
 *
5
 * Based on https://pippinsplugins.com/batch-processing-for-big-data/
6
 *
7
 * @package  WooCommerce/Export
8
 * @version  3.1.0
9
 */
10
11 1
if ( ! defined( 'ABSPATH' ) ) {
12
	exit;
13
}
14
15
/**
16
 * Include dependencies.
17
 */
18 1
if ( ! class_exists( 'WC_CSV_Exporter', false ) ) {
19 1
	require_once WC_ABSPATH . 'includes/export/abstract-wc-csv-exporter.php';
20
}
21
22
/**
23
 * WC_CSV_Exporter Class.
24
 */
25
abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
26
27
	/**
28
	 * Page being exported
29
	 *
30
	 * @var integer
31
	 */
32
	protected $page = 1;
33
34
	/**
35
	 * Constructor.
36
	 */
37 4
	public function __construct() {
38 4
		$this->column_names = $this->get_default_column_names();
39
	}
40
41
	/**
42
	 * Get file path to export to.
43
	 *
44
	 * @return string
45
	 */
46
	protected function get_file_path() {
47
		$upload_dir = wp_upload_dir();
48
		return trailingslashit( $upload_dir['basedir'] ) . $this->get_filename();
49
	}
50
51
	/**
52
	 * Get the file contents.
53
	 *
54
	 * @since 3.1.0
55
	 * @return string
56
	 */
57
	public function get_file() {
58
		$file = '';
59
		if ( @file_exists( $this->get_file_path() ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
60
			$file = @file_get_contents( $this->get_file_path() ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPress.WP.AlternativeFunctions.file_system_read_file_get_contents
61
		} else {
62
			@file_put_contents( $this->get_file_path(), '' ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_file_put_contents, Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
63
			@chmod( $this->get_file_path(), 0664 ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.chmod_chmod, WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents, Generic.PHP.NoSilencedErrors.Discouraged
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
64
		}
65
		return $file;
66
	}
67
68
	/**
69
	 * Serve the file and remove once sent to the client.
70
	 *
71
	 * @since 3.1.0
72
	 */
73
	public function export() {
74
		$this->send_headers();
75
		$this->send_content( $this->get_file() );
76
		@unlink( $this->get_file_path() ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink, Generic.PHP.NoSilencedErrors.Discouraged
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
77
		die();
78
	}
79
80
	/**
81
	 * Generate the CSV file.
82
	 *
83
	 * @since 3.1.0
84
	 */
85
	public function generate_file() {
86
		if ( 1 === $this->get_page() ) {
87
			@unlink( $this->get_file_path() ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink, Generic.PHP.NoSilencedErrors.Discouraged,
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
88
		}
89
		$this->prepare_data_to_export();
90
		$this->write_csv_data( $this->get_csv_data() );
91
	}
92
93
	/**
94
	 * Write data to the file.
95
	 *
96
	 * @since 3.1.0
97
	 * @param string $data Data.
98
	 */
99
	protected function write_csv_data( $data ) {
100
		$file = $this->get_file();
101
102
		// Add columns when finished.
103
		if ( 100 === $this->get_percent_complete() ) {
104
			$file = chr( 239 ) . chr( 187 ) . chr( 191 ) . $this->export_column_headers() . $file;
105
		}
106
107
		$file .= $data;
108
		@file_put_contents( $this->get_file_path(), $file ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_file_put_contents, Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
109
	}
110
111
	/**
112
	 * Get page.
113
	 *
114
	 * @since 3.1.0
115
	 * @return int
116
	 */
117 1
	public function get_page() {
118 1
		return $this->page;
119
	}
120
121
	/**
122
	 * Set page.
123
	 *
124
	 * @since 3.1.0
125
	 * @param int $page Page Nr.
126
	 */
127
	public function set_page( $page ) {
128
		$this->page = absint( $page );
129
	}
130
131
	/**
132
	 * Get count of records exported.
133
	 *
134
	 * @since 3.1.0
135
	 * @return int
136
	 */
137
	public function get_total_exported() {
138
		return ( ( $this->get_page() - 1 ) * $this->get_limit() ) + $this->exported_row_count;
139
	}
140
141
	/**
142
	 * Get total % complete.
143
	 *
144
	 * @since 3.1.0
145
	 * @return int
146
	 */
147
	public function get_percent_complete() {
148
		return $this->total_rows ? floor( ( $this->get_total_exported() / $this->total_rows ) * 100 ) : 100;
149
	}
150
}
151