Completed
Push — master ( 5f46f6...9c1aa8 )
by Mike
09:11 queued 21s
created

WC_Admin_Notices::theme_check_notice()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 5
Ratio 71.43 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
nc 2
nop 0
dl 5
loc 7
rs 9.4285
c 1
b 0
f 0
1
<?php
1 ignored issue
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 18 and the first side effect is on line 12.

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
 * Display notices in admin
4
 *
5
 * @author      WooThemes
6
 * @category    Admin
7
 * @package     WooCommerce/Admin
8
 * @version     2.3.0
9
 */
10
11
if ( ! defined( 'ABSPATH' ) ) {
12
	exit;
13
}
14
15
/**
16
 * WC_Admin_Notices Class.
17
 */
18
class WC_Admin_Notices {
19
20
	/**
21
	 * Array of notices - name => callback.
22
	 * @var array
23
	 */
24
	private static $core_notices = array(
25
		'install'             => 'install_notice',
26
		'update'              => 'update_notice',
27
		'updating'            => 'updating_notice',
28
		'template_files'      => 'template_file_check_notice',
29
		'theme_support'       => 'theme_check_notice',
30
		'legacy_shipping'     => 'legacy_shipping_notice',
31
		'no_shipping_methods' => 'no_shipping_methods_notice',
32
		'simplify_commerce'   => 'simplify_commerce_notice',
33
	);
34
35
	/**
36
	 * Stores notices.
37
	 * @var array
38
	 */
39
	private static $notices = array();
40
41
	/**
42
	 * Constructor.
43
	 */
44
	public static function init() {
45
		self::$notices = get_option( 'woocommerce_admin_notices', array() );
46
47
		add_action( 'switch_theme', array( __CLASS__, 'reset_admin_notices' ) );
48
		add_action( 'woocommerce_installed', array( __CLASS__, 'reset_admin_notices' ) );
49
		add_action( 'wp_loaded', array( __CLASS__, 'hide_notices' ) );
50
		add_action( 'shutdown', array( __CLASS__, 'store_notices' ) );
51
52
		if ( current_user_can( 'manage_woocommerce' ) ) {
53
			add_action( 'admin_print_styles', array( __CLASS__, 'add_notices' ) );
54
		}
55
	}
56
57
	/**
58
	 * Store notices to DB
59
	 */
60
	public static function store_notices() {
61
		update_option( 'woocommerce_admin_notices', self::get_notices() );
62
	}
63
64
	/**
65
	 * Get notices
66
	 * @return array
67
	 */
68
	public static function get_notices() {
69
		return self::$notices;
70
	}
71
72
	/**
73
	 * Remove all notices.
74
	 */
75
	public static function remove_all_notices() {
76
		self::$notices = array();
77
	}
78
79
	/**
80
	 * Reset notices for themes when switched or a new version of WC is installed.
81
	 */
82
	public static function reset_admin_notices() {
83 View Code Duplication
		if ( ! current_theme_supports( 'woocommerce' ) && ! in_array( get_option( 'template' ), wc_get_core_supported_themes() ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
			self::add_notice( 'theme_support' );
85
		}
86
87
		$simplify_options = get_option( 'woocommerce_simplify_commerce_settings', array() );
88
89
		if ( ! class_exists( 'WC_Gateway_Simplify_Commerce_Loader' ) && ! empty( $simplify_options['enabled'] ) && 'yes' === $simplify_options['enabled'] ) {
90
			WC_Admin_Notices::add_notice( 'simplify_commerce' );
91
		}
92
93
		self::add_notice( 'template_files' );
94
	}
95
96
	/**
97
	 * Show a notice.
98
	 * @param string $name
99
	 */
100
	public static function add_notice( $name ) {
101
		self::$notices = array_unique( array_merge( self::get_notices(), array( $name ) ) );
102
	}
103
104
	/**
105
	 * Remove a notice from being displayed.
106
	 * @param  string $name
107
	 */
108
	public static function remove_notice( $name ) {
109
		self::$notices = array_diff( self::get_notices(), array( $name ) );
110
		delete_option( 'woocommerce_admin_notice_' . $name );
111
	}
112
113
	/**
114
	 * See if a notice is being shown.
115
	 * @param  string  $name
116
	 * @return boolean
117
	 */
118
	public static function has_notice( $name ) {
119
		return in_array( $name, self::get_notices() );
120
	}
121
122
	/**
123
	 * Hide a notice if the GET variable is set.
124
	 */
125
	public static function hide_notices() {
126
		if ( isset( $_GET['wc-hide-notice'] ) && isset( $_GET['_wc_notice_nonce'] ) ) {
127
			if ( ! wp_verify_nonce( $_GET['_wc_notice_nonce'], 'woocommerce_hide_notices_nonce' ) ) {
128
				wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
129
			}
130
131
			if ( ! current_user_can( 'manage_woocommerce' ) ) {
132
				wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce' ) );
133
			}
134
135
			$hide_notice = sanitize_text_field( $_GET['wc-hide-notice'] );
136
			self::remove_notice( $hide_notice );
137
			do_action( 'woocommerce_hide_' . $hide_notice . '_notice' );
138
		}
139
	}
140
141
	/**
142
	 * Add notices + styles if needed.
143
	 */
144
	public static function add_notices() {
145
		$notices = self::get_notices();
146
147
		if ( $notices ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $notices 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...
148
			wp_enqueue_style( 'woocommerce-activation', plugins_url(  '/assets/css/activation.css', WC_PLUGIN_FILE ) );
149
			foreach ( $notices as $notice ) {
150
				if ( ! empty( self::$core_notices[ $notice ] ) && apply_filters( 'woocommerce_show_admin_notice', true, $notice ) ) {
151
					add_action( 'admin_notices', array( __CLASS__, self::$core_notices[ $notice ] ) );
152
				} else {
153
					add_action( 'admin_notices', array( __CLASS__, 'output_custom_notices' ) );
154
				}
155
			}
156
		}
157
	}
158
159
	/**
160
	 * Add a custom notice.
161
	 * @param string $name
162
	 * @param string $notice_html
163
	 */
164
	public static function add_custom_notice( $name, $notice_html ) {
165
		self::add_notice( $name );
166
		update_option( 'woocommerce_admin_notice_' . $name, wp_kses_post( $notice_html ) );
167
	}
168
169
	/**
170
	 * Output any stored custom notices.
171
	 */
172
	public static function output_custom_notices() {
173
		$notices = self::get_notices();
174
175
		if ( $notices ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $notices 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...
176
			foreach ( $notices as $notice ) {
177
				if ( empty( self::$core_notices[ $notice ] ) ) {
178
					$notice_html = get_option( 'woocommerce_admin_notice_' . $notice );
179
180
					if ( $notice_html ) {
181
						include( 'views/html-notice-custom.php' );
182
					}
183
				}
184
			}
185
		}
186
	}
187
188
	/**
189
	 * If we need to update, include a message with the update button.
190
	 */
191
	public static function update_notice() {
192
		include( 'views/html-notice-update.php' );
193
	}
194
195
	/**
196
	 * If we are updating, show progress.
197
	 */
198
	public static function updating_notice() {
199
		if ( version_compare( get_option( 'woocommerce_db_version' ), WC_VERSION, '<' ) ) {
200
			include( 'views/html-notice-updating.php' );
201
		} else {
202
			include( 'views/html-notice-updated.php' );
203
		}
204
	}
205
206
	/**
207
	 * If we have just installed, show a message with the install pages button.
208
	 */
209
	public static function install_notice() {
210
		include( 'views/html-notice-install.php' );
211
	}
212
213
	/**
214
	 * Show the Theme Check notice.
215
	 */
216
	public static function theme_check_notice() {
217 View Code Duplication
		if ( ! current_theme_supports( 'woocommerce' ) && ! in_array( get_option( 'template' ), wc_get_core_supported_themes() ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
			include( 'views/html-notice-theme-support.php' );
219
		} else {
220
			self::remove_notice( 'theme_support' );
221
		}
222
	}
223
224
	/**
225
	 * Show a notice highlighting bad template files.
226
	 */
227
	public static function template_file_check_notice() {
228
		$core_templates = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates' );
229
		$outdated       = false;
230
231
		foreach ( $core_templates as $file ) {
232
233
			$theme_file = false;
234 View Code Duplication
			if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
				$theme_file = get_stylesheet_directory() . '/' . $file;
236
			} elseif ( file_exists( get_stylesheet_directory() . '/woocommerce/' . $file ) ) {
237
				$theme_file = get_stylesheet_directory() . '/woocommerce/' . $file;
238
			} elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
239
				$theme_file = get_template_directory() . '/' . $file;
240
			} elseif( file_exists( get_template_directory() . '/woocommerce/' . $file ) ) {
241
				$theme_file = get_template_directory() . '/woocommerce/' . $file;
242
			}
243
244
			if ( $theme_file !== false ) {
245
				$core_version  = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file );
246
				$theme_version = WC_Admin_Status::get_file_version( $theme_file );
247
248
				if ( $core_version && $theme_version && version_compare( $theme_version, $core_version, '<' ) ) {
249
					$outdated = true;
250
					break;
251
				}
252
			}
253
		}
254
255
		if ( $outdated ) {
256
			include( 'views/html-notice-template-check.php' );
257
		} else {
258
			self::remove_notice( 'template_files' );
259
		}
260
	}
261
262
	/**
263
	 * Show a notice asking users to convert to shipping zones.
264
	 */
265
	public static function legacy_shipping_notice() {
266
		$maybe_load_legacy_methods = array( 'flat_rate', 'free_shipping', 'international_delivery', 'local_delivery', 'local_pickup' );
267
		$enabled                   = false;
268
269
		foreach ( $maybe_load_legacy_methods as $method ) {
270
			$options = get_option( 'woocommerce_' . $method . '_settings' );
271
			if ( $options && isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) {
272
				$enabled = true;
273
			}
274
		}
275
276
		if ( $enabled ) {
277
			include( 'views/html-notice-legacy-shipping.php' );
278
		} else {
279
			self::remove_notice( 'template_files' );
280
		}
281
	}
282
283
	/**
284
	 * No shipping methods.
285
	 */
286
	public static function no_shipping_methods_notice() {
287
		if ( wc_shipping_enabled() && ( empty( $_GET['page'] ) || empty( $_GET['tab'] ) || 'wc-settings' !== $_GET['page'] || 'shipping' !== $_GET['tab'] ) ) {
288
			global $wpdb;
289
290
			$product_count = wp_count_posts( 'product' );
291
			$method_count  = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_shipping_zone_methods" ) );
292
293
			if ( $product_count->publish > 0 && 0 === $method_count ) {
294
				include( 'views/html-notice-no-shipping-methods.php' );
295
			}
296
297
			if ( $method_count > 0 ) {
298
				self::remove_notice( 'no_shipping_methods' );
299
			}
300
		}
301
	}
302
303
	/**
304
	 * Simplify Commerce is being removed from core.
305
	 */
306
	public static function simplify_commerce_notice() {
307
		if ( class_exists( 'WC_Gateway_Simplify_Commerce_Loader' ) ) {
308
			self::remove_notice( 'simplify_commerce' );
309
			return;
310
		}
311
		if ( empty( $_GET['action'] ) ) {
312
			include( 'views/html-notice-simplify-commerce.php' );
313
		}
314
	}
315
}
316
317
WC_Admin_Notices::init();
318