WooCommerce Admin - Version 2.2.7

Version Description

2021-09-21 =

  • Fix unsecured reports

=

Download this release

Release Info

Developer joshuaflow
Plugin Icon 128x128 WooCommerce Admin
Version 2.2.7
Comparing to
See all releases

Code changes from version 2.2.6 to 2.2.7

includes/wc-admin-update-functions.php CHANGED
@@ -9,7 +9,9 @@
9
 
10
  use \Automattic\WooCommerce\Admin\Install as Installer;
11
  use \Automattic\WooCommerce\Admin\Notes\Notes;
 
12
  use \Automattic\WooCommerce\Admin\Notes\DeactivatePlugin;
 
13
 
14
  /**
15
  * Update order stats `status` index length.
@@ -152,3 +154,95 @@ function wc_admin_update_170_homescreen_layout() {
152
  function wc_admin_update_170_db_version() {
153
  Installer::update_db_version( '1.7.0' );
154
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  use \Automattic\WooCommerce\Admin\Install as Installer;
11
  use \Automattic\WooCommerce\Admin\Notes\Notes;
12
+ use \Automattic\WooCommerce\Admin\Notes\UnsecuredReportFiles;
13
  use \Automattic\WooCommerce\Admin\Notes\DeactivatePlugin;
14
+ use \Automattic\WooCommerce\Admin\ReportExporter;
15
 
16
  /**
17
  * Update order stats `status` index length.
154
  function wc_admin_update_170_db_version() {
155
  Installer::update_db_version( '1.7.0' );
156
  }
157
+
158
+ /**
159
+ * Delete the preexisting export files.
160
+ */
161
+ function wc_admin_update_227_delete_report_downloads() {
162
+ $upload_dir = wp_upload_dir();
163
+ $base_dir = trailingslashit( $upload_dir['basedir'] );
164
+
165
+ $failed_files = array();
166
+ $exports_status = get_option( ReportExporter::EXPORT_STATUS_OPTION, array() );
167
+ $has_failure = false;
168
+
169
+ if ( ! is_array( $exports_status ) ) {
170
+ // This is essentially the same path as files failing deletion. Handle as such.
171
+ return;
172
+ }
173
+
174
+ // Delete all export files based on the status option values.
175
+ foreach ( $exports_status as $key => $progress ) {
176
+ list( $report_type, $export_id ) = explode( ':', $key );
177
+
178
+ if ( ! $export_id ) {
179
+ continue;
180
+ }
181
+
182
+ $file = "{$base_dir}wc-{$report_type}-report-export-{$export_id}.csv";
183
+ $header = $file . '.headers';
184
+
185
+ // phpcs:ignore
186
+ if ( @file_exists( $file ) && false === @unlink( $file ) ) {
187
+ array_push( $failed_files, $file );
188
+ }
189
+
190
+ // phpcs:ignore
191
+ if ( @file_exists( $header ) && false === @unlink( $header ) ) {
192
+ array_push( $failed_files, $header );
193
+ }
194
+ }
195
+
196
+ // If the status option was missing or corrupt, there will be files left over.
197
+ $potential_exports = glob( $base_dir . 'wc-*-report-export-*.csv' );
198
+ $reports_pattern = '(revenue|products|variations|orders|categories|coupons|taxes|stock|customers|downloads)';
199
+
200
+ /**
201
+ * Look for files we can be reasonably sure were created by the report export.
202
+ *
203
+ * Export files we created will match the 'wc-*-report-export-*.csv' glob, with
204
+ * the first wildcard being one of the exportable report slugs, and the second
205
+ * being an integer with 11-14 digits (from microtime()'s output) that represents
206
+ * a time in the past.
207
+ */
208
+ foreach ( $potential_exports as $potential_export ) {
209
+ $matches = array();
210
+ // See if the filename matches an unfiltered export pattern.
211
+ if ( ! preg_match( "/wc-{$reports_pattern}-report-export-(?P<export_id>\d{11,14})\.csv\$/", $potential_export, $matches ) ) {
212
+ $has_failure = true;
213
+ continue;
214
+ }
215
+
216
+ // Validate the timestamp (anything in the past).
217
+ $timestamp = (int) substr( $matches['export_id'], 0, 10 );
218
+
219
+ if ( ! $timestamp || $timestamp > time() ) {
220
+ $has_failure = true;
221
+ continue;
222
+ }
223
+
224
+ // phpcs:ignore
225
+ if ( false === @unlink( $potential_export ) ) {
226
+ array_push( $failed_files, $potential_export );
227
+ }
228
+ }
229
+
230
+ // Try deleting failed files once more.
231
+ foreach ( $failed_files as $failed_file ) {
232
+ // phpcs:ignore
233
+ if ( false === @unlink( $failed_file ) ) {
234
+ $has_failure = true;
235
+ }
236
+ }
237
+
238
+ if ( $has_failure ) {
239
+ UnsecuredReportFiles::possibly_add_note();
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Update DB Version.
245
+ */
246
+ function wc_admin_update_227_db_version() {
247
+ Installer::update_db_version( '2.2.7' );
248
+ }
languages/woocommerce-admin.pot CHANGED
@@ -2,7 +2,7 @@
2
  # This file is distributed under the same license as the WooCommerce Admin package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WooCommerce Admin 2.2.6\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-admin\n"
8
  "POT-Creation-Date: 2021-05-07 21:22:43+00:00\n"
2
  # This file is distributed under the same license as the WooCommerce Admin package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WooCommerce Admin 2.2.7\n
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-admin\n"
8
  "POT-Creation-Date: 2021-05-07 21:22:43+00:00\n"
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: ecommerce, e-commerce, store, sales, reports, analytics, dashboard, activi
4
  Requires at least: 5.4.0
5
  Tested up to: 5.7.0
6
  Requires PHP: 7.0
7
- Stable tag: 2.2.6
8
  License: GPLv3
9
  License URI: https://github.com/woocommerce/woocommerce-admin/blob/main/license.txt
10
 
@@ -73,6 +73,11 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
73
 
74
  == Changelog ==
75
 
 
 
 
 
 
76
  == 2.2.6 5/7/2021 ==
77
  - Fix: Address an issue with OBW when installing only WooCommerce payments and Jetpack. #6957
78
 
4
  Requires at least: 5.4.0
5
  Tested up to: 5.7.0
6
  Requires PHP: 7.0
7
+ Stable tag: 2.2.7
8
  License: GPLv3
9
  License URI: https://github.com/woocommerce/woocommerce-admin/blob/main/license.txt
10
 
73
 
74
  == Changelog ==
75
 
76
+ = 2.2.7 2021-09-21 =
77
+
78
+ - Fix unsecured reports
79
+
80
+
81
  == 2.2.6 5/7/2021 ==
82
  - Fix: Address an issue with OBW when installing only WooCommerce payments and Jetpack. #6957
83
 
src/Composer/Package.php CHANGED
@@ -24,7 +24,7 @@ class Package {
24
  *
25
  * @var string
26
  */
27
- const VERSION = '2.2.6';
28
 
29
  /**
30
  * Package active.
24
  *
25
  * @var string
26
  */
27
+ const VERSION = '2.2.7';
28
 
29
  /**
30
  * Package active.
src/FeaturePlugin.php CHANGED
@@ -155,7 +155,7 @@ class FeaturePlugin {
155
  $this->define( 'WC_ADMIN_PLUGIN_FILE', WC_ADMIN_ABSPATH . 'woocommerce-admin.php' );
156
  // WARNING: Do not directly edit this version number constant.
157
  // It is updated as part of the prebuild process from the package.json value.
158
- $this->define( 'WC_ADMIN_VERSION_NUMBER', '2.2.6' );
159
  }
160
 
161
  /**
155
  $this->define( 'WC_ADMIN_PLUGIN_FILE', WC_ADMIN_ABSPATH . 'woocommerce-admin.php' );
156
  // WARNING: Do not directly edit this version number constant.
157
  // It is updated as part of the prebuild process from the package.json value.
158
+ $this->define( 'WC_ADMIN_VERSION_NUMBER', '2.2.7' );
159
  }
160
 
161
  /**
src/Install.php CHANGED
@@ -57,6 +57,10 @@ class Install {
57
  'wc_admin_update_170_homescreen_layout',
58
  'wc_admin_update_170_db_version',
59
  ),
 
 
 
 
60
  );
61
 
62
  /**
57
  'wc_admin_update_170_homescreen_layout',
58
  'wc_admin_update_170_db_version',
59
  ),
60
+ '2.2.7' => array(
61
+ 'wc_admin_update_227_delete_report_downloads',
62
+ 'wc_admin_update_227_db_version',
63
+ ),
64
  );
65
 
66
  /**
src/Notes/UnsecuredReportFiles.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Admin Unsecured Files Note.
4
+ *
5
+ * Adds a warning about potentially unsecured files.
6
+ */
7
+
8
+ namespace Automattic\WooCommerce\Admin\Notes;
9
+
10
+ defined( 'ABSPATH' ) || exit;
11
+
12
+ if ( ! class_exists( Note::class ) ) {
13
+ class_alias( WC_Admin_Note::class, Note::class );
14
+ }
15
+
16
+ /**
17
+ * Unsecured_Report_Files
18
+ */
19
+ class UnsecuredReportFiles {
20
+
21
+ /**
22
+ * Name of the note for use in the database.
23
+ */
24
+ const NOTE_NAME = 'wc-admin-remove-unsecured-report-files';
25
+
26
+ /**
27
+ * Get the note.
28
+ *
29
+ * @return Note|null
30
+ */
31
+ public static function get_note() {
32
+ $note = new Note();
33
+ $note->set_title( __( 'Potentially unsecured files were found in your uploads directory', 'woocommerce-admin' ) );
34
+ $note->set_content(
35
+ sprintf(
36
+ /* translators: 1: opening analytics docs link tag. 2: closing link tag */
37
+ __( 'Files that may contain %1$sstore analytics%2$s reports were found in your uploads directory - we recommend assessing and deleting any such files.', 'woocommerce-admin' ),
38
+ '<a href="https://docs.woocommerce.com/document/woocommerce-analytics/" target="_blank">',
39
+ '</a>'
40
+ )
41
+ );
42
+ $note->set_content_data( (object) array() );
43
+ $note->set_type( Note::E_WC_ADMIN_NOTE_ERROR );
44
+ $note->set_name( self::NOTE_NAME );
45
+ $note->set_source( 'woocommerce-admin' );
46
+ $note->add_action(
47
+ 'learn-more',
48
+ __( 'Learn more', 'woocommerce-admin' ),
49
+ 'https://developer.woocommerce.com/?p=10410',
50
+ Note::E_WC_ADMIN_NOTE_UNACTIONED,
51
+ true
52
+ );
53
+ $note->add_action(
54
+ 'dismiss',
55
+ __( 'Dismiss', 'woocommerce-admin' ),
56
+ wc_admin_url(),
57
+ Note::E_WC_ADMIN_NOTE_ACTIONED,
58
+ false
59
+ );
60
+
61
+ return $note;
62
+ }
63
+
64
+ /**
65
+ * Add the note if it passes predefined conditions.
66
+ */
67
+ public static function possibly_add_note() {
68
+ $note = self::get_note();
69
+
70
+ if ( self::note_exists() ) {
71
+ return;
72
+ }
73
+
74
+ $note->save();
75
+ }
76
+
77
+ /**
78
+ * Check if the note has been previously added.
79
+ */
80
+ public static function note_exists() {
81
+ $data_store = \WC_Data_Store::load( 'admin-note' );
82
+ $note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
83
+ return ! empty( $note_ids );
84
+ }
85
+
86
+ }
src/ReportCSVExporter.php CHANGED
@@ -52,6 +52,8 @@ class ReportCSVExporter extends \WC_CSV_Batch_Exporter {
52
  public function __construct( $type = false, $args = array() ) {
53
  parent::__construct();
54
 
 
 
55
  if ( ! empty( $type ) ) {
56
  $this->set_report_type( $type );
57
  $this->set_column_names( $this->get_report_columns() );
@@ -62,6 +64,59 @@ class ReportCSVExporter extends \WC_CSV_Batch_Exporter {
62
  }
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * Setter for report type.
67
  *
52
  public function __construct( $type = false, $args = array() ) {
53
  parent::__construct();
54
 
55
+ self::maybe_create_directory();
56
+
57
  if ( ! empty( $type ) ) {
58
  $this->set_report_type( $type );
59
  $this->set_column_names( $this->get_report_columns() );
64
  }
65
  }
66
 
67
+ /**
68
+ * Create the directory for reports if it does not yet exist.
69
+ */
70
+ public static function maybe_create_directory() {
71
+ $reports_dir = self::get_reports_directory();
72
+
73
+ $files = array(
74
+ array(
75
+ 'base' => $reports_dir,
76
+ 'file' => '.htaccess',
77
+ 'content' => 'DirectoryIndex index.php index.html' . PHP_EOL . 'deny from all',
78
+ ),
79
+ array(
80
+ 'base' => $reports_dir,
81
+ 'file' => 'index.html',
82
+ 'content' => '',
83
+ ),
84
+ );
85
+
86
+ foreach ( $files as $file ) {
87
+ if ( ! file_exists( trailingslashit( $file['base'] ) ) ) {
88
+ wp_mkdir_p( $file['base'] );
89
+ }
90
+ if ( ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
91
+ $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'wb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
92
+ if ( $file_handle ) {
93
+ fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite
94
+ fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Get report uploads directory.
102
+ *
103
+ * @return string
104
+ */
105
+ public static function get_reports_directory() {
106
+ $upload_dir = wp_upload_dir();
107
+ return trailingslashit( $upload_dir['basedir'] ) . 'woocommerce_uploads/reports/';
108
+ }
109
+
110
+ /**
111
+ * Get file path to export to.
112
+ *
113
+ * @return string
114
+ */
115
+ protected function get_file_path() {
116
+ return self::get_reports_directory() . $this->get_filename();
117
+ }
118
+
119
+
120
  /**
121
  * Setter for report type.
122
  *
vendor/composer/jetpack_autoload_psr4.php CHANGED
@@ -11,7 +11,7 @@ return array(
11
  'path' => array( $vendorDir . '/composer/installers/src/Composer/Installers' )
12
  ),
13
  'Automattic\\WooCommerce\\Admin\\' => array(
14
- 'version' => '2.2.6.0',
15
  'path' => array( $baseDir . '/src' )
16
  ),
17
  'Automattic\\Jetpack\\Autoloader\\' => array(
11
  'path' => array( $vendorDir . '/composer/installers/src/Composer/Installers' )
12
  ),
13
  'Automattic\\WooCommerce\\Admin\\' => array(
14
+ 'version' => '2.2.7.0',
15
  'path' => array( $baseDir . '/src' )
16
  ),
17
  'Automattic\\Jetpack\\Autoloader\\' => array(
woocommerce-admin.php CHANGED
@@ -7,7 +7,7 @@
7
  * Author URI: https://woocommerce.com/
8
  * Text Domain: woocommerce-admin
9
  * Domain Path: /languages
10
- * Version: 2.2.6
11
  * Requires at least: 5.4
12
  * Requires PHP: 7.0
13
  *
7
  * Author URI: https://woocommerce.com/
8
  * Text Domain: woocommerce-admin
9
  * Domain Path: /languages
10
+ * Version: 2.2.7
11
  * Requires at least: 5.4
12
  * Requires PHP: 7.0
13
  *