Completed
Push — fix/flickr-shortcode ( 3e5712...02d728 )
by
unknown
24:33 queued 14:33
created

Jetpack_EU_Cookie_Law_Widget   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 286
Duplicated Lines 12.94 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 37
loc 286
rs 8.96
c 0
b 0
f 0
wmc 43
lcom 1
cbo 3

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 16 16 3
A defaults() 0 17 3
A form() 0 18 2
F update() 14 67 21
A filter_value() 7 7 4
A enqueue_frontend_scripts() 0 16 3
B widget() 0 40 7

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Jetpack_EU_Cookie_Law_Widget often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Jetpack_EU_Cookie_Law_Widget, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
use Automattic\Jetpack\Assets;
4
5
/**
6
 * Disable direct access/execution to/of the widget code.
7
 */
8
if ( ! defined( 'ABSPATH' ) ) {
9
	exit;
10
}
11
12
if ( ! class_exists( 'Jetpack_EU_Cookie_Law_Widget' ) ) {
13
	/**
14
	 * EU Cookie Law Widget
15
	 *
16
	 * Display the EU Cookie Law banner in the bottom part of the screen.
17
	 */
18
	class Jetpack_EU_Cookie_Law_Widget extends WP_Widget {
19
		/**
20
		 * EU Cookie Law cookie name.
21
		 *
22
		 * @var string
23
		 */
24
		public static $cookie_name = 'eucookielaw';
25
26
		/**
27
		 * Default hide options.
28
		 *
29
		 * @var array
30
		 */
31
		private $hide_options = array(
32
			'button',
33
			'scroll',
34
			'time',
35
		);
36
37
		/**
38
		 * Default text options.
39
		 *
40
		 * @var array
41
		 */
42
		private $text_options = array(
43
			'default',
44
			'custom',
45
		);
46
47
		/**
48
		 * Default color scheme options.
49
		 *
50
		 * @var array
51
		 */
52
		private $color_scheme_options = array(
53
			'default',
54
			'negative',
55
		);
56
57
		/**
58
		 * Default policy URL options.
59
		 *
60
		 * @var array
61
		 */
62
		private $policy_url_options = array(
63
			'default',
64
			'custom',
65
		);
66
67
		/**
68
		 * Widget position options.
69
		 *
70
		 * @var array
71
		 */
72
		private $position_options = array(
73
			'bottom',
74
			'top',
75
		);
76
77
		/**
78
		 * Constructor.
79
		 */
80 View Code Duplication
		function __construct() {
81
			parent::__construct(
82
				'eu_cookie_law_widget',
83
				/** This filter is documented in modules/widgets/facebook-likebox.php */
84
				apply_filters( 'jetpack_widget_name', esc_html__( 'Cookies & Consents Banner', 'jetpack' ) ),
85
				array(
86
					'description'                 => esc_html__( 'Display a banner for EU Cookie Law and GDPR compliance.', 'jetpack' ),
87
					'customize_selective_refresh' => true,
88
				),
89
				array()
90
			);
91
92
			if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
93
				add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_scripts' ) );
94
			}
95
		}
96
97
		/**
98
		 * Enqueue scripts and styles.
99
		 */
100
		function enqueue_frontend_scripts() {
101
			wp_enqueue_style( 'eu-cookie-law-style', plugins_url( 'eu-cookie-law/style.css', __FILE__ ), array(), JETPACK__VERSION );
102
103
			if ( ! class_exists( 'Jetpack_AMP_Support' ) || ! Jetpack_AMP_Support::is_amp_request() ) {
104
				wp_enqueue_script(
105
					'eu-cookie-law-script',
106
					Assets::get_file_url_for_environment(
107
						'_inc/build/widgets/eu-cookie-law/eu-cookie-law.min.js',
108
						'modules/widgets/eu-cookie-law/eu-cookie-law.js'
109
					),
110
					array(),
111
					'20180522',
112
					true
113
				);
114
			}
115
		}
116
117
		/**
118
		 * Return an associative array of default values.
119
		 *
120
		 * These values are used in new widgets.
121
		 *
122
		 * @return array Default values for the widget options.
123
		 */
124
		public function defaults() {
125
			return array(
126
				'hide'               => $this->hide_options[0],
127
				'hide-timeout'       => 30,
128
				'consent-expiration' => 180,
129
				'text'               => $this->text_options[0],
130
				'customtext'         => '',
131
				'color-scheme'       => $this->color_scheme_options[0],
132
				'policy-url'         => get_option( 'wp_page_for_privacy_policy' ) ? $this->policy_url_options[1] : $this->policy_url_options[0],
133
				'default-policy-url' => 'https://automattic.com/cookies/',
134
				'custom-policy-url'  => get_option( 'wp_page_for_privacy_policy' ) ? get_permalink( (int) get_option( 'wp_page_for_privacy_policy' ) ) : '',
135
				'position'           => $this->position_options[0],
136
				'policy-link-text'   => esc_html__( 'Cookie Policy', 'jetpack' ),
137
				'button'             => esc_html__( 'Close and accept', 'jetpack' ),
138
				'default-text'       => esc_html__( "Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use. \r\nTo find out more, including how to control cookies, see here:", 'jetpack' ),
139
			);
140
		}
141
142
		/**
143
		 * Front-end display of the widget.
144
		 *
145
		 * @param array $args     Widget arguments.
146
		 * @param array $instance Saved values from database.
147
		 */
148
		public function widget( $args, $instance ) {
149
			/**
150
			 * Filters the display of the EU Cookie Law widget.
151
			 *
152
			 * @since 6.1.1
153
			 *
154
			 * @param bool true Should the EU Cookie Law widget be disabled. Default to false.
155
			 */
156
			if ( apply_filters( 'jetpack_disable_eu_cookie_law_widget', false ) ) {
157
				return;
158
			}
159
160
			$instance = wp_parse_args( $instance, $this->defaults() );
0 ignored issues
show
Documentation introduced by
$this->defaults() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
161
162
			if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
163
				require dirname( __FILE__ ) . '/eu-cookie-law/widget-amp.php';
164
				return;
165
			}
166
167
			$classes         = array();
168
			$classes['hide'] = 'hide-on-' . esc_attr( $instance['hide'] );
169
			if ( 'negative' === $instance['color-scheme'] ) {
170
				$classes['negative'] = 'negative';
171
			}
172
173
			if ( 'top' === $instance['position'] ) {
174
				$classes['top'] = 'top';
175
			}
176
177
			if ( Jetpack::is_module_active( 'wordads' ) ) {
178
				$classes['ads']  = 'ads-active';
179
				$classes['hide'] = 'hide-on-button';
180
			}
181
182
			echo $args['before_widget'];
183
			require( dirname( __FILE__ ) . '/eu-cookie-law/widget.php' );
184
			echo $args['after_widget'];
185
			/** This action is already documented in modules/widgets/gravatar-profile.php */
186
			do_action( 'jetpack_stats_extra', 'widget_view', 'eu_cookie_law' );
187
		}
188
189
		/**
190
		 * Back-end widget form.
191
		 *
192
		 * @param array $instance Previously saved values from database.
193
		 */
194
		public function form( $instance ) {
195
			$instance = wp_parse_args( $instance, $this->defaults() );
0 ignored issues
show
Documentation introduced by
$this->defaults() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
196
			if ( Jetpack::is_module_active( 'wordads' ) ) {
197
				$instance['hide'] = 'button';
198
			}
199
200
			wp_enqueue_script(
201
				'eu-cookie-law-widget-admin',
202
				Assets::get_file_url_for_environment(
203
					'_inc/build/widgets/eu-cookie-law/eu-cookie-law-admin.min.js',
204
					'modules/widgets/eu-cookie-law/eu-cookie-law-admin.js'
205
				),
206
				array( 'jquery' ),
207
				20180417
208
			);
209
210
			require( dirname( __FILE__ ) . '/eu-cookie-law/form.php' );
211
		}
212
213
		/**
214
		 * Sanitize widget form values as they are saved.
215
		 *
216
		 * @param  array $new_instance Values just sent to be saved.
217
		 * @param  array $old_instance Previously saved values from database.
218
		 * @return array Updated safe values to be saved.
219
		 */
220
		public function update( $new_instance, $old_instance ) {
221
			$instance = array();
222
			$defaults = $this->defaults();
223
224
			$instance['hide']         = $this->filter_value( isset( $new_instance['hide'] ) ? $new_instance['hide'] : '', $this->hide_options );
225
			$instance['text']         = $this->filter_value( isset( $new_instance['text'] ) ? $new_instance['text'] : '', $this->text_options );
226
			$instance['color-scheme'] = $this->filter_value( isset( $new_instance['color-scheme'] ) ? $new_instance['color-scheme'] : '', $this->color_scheme_options );
227
			$instance['policy-url']   = $this->filter_value( isset( $new_instance['policy-url'] ) ? $new_instance['policy-url'] : '', $this->policy_url_options );
228
			$instance['position']     = $this->filter_value( isset( $new_instance['position'] ) ? $new_instance['position'] : '', $this->position_options );
229
230 View Code Duplication
			if ( isset( $new_instance['hide-timeout'] ) ) {
231
				// Time can be a value between 3 and 1000 seconds.
232
				$instance['hide-timeout'] = min( 1000, max( 3, intval( $new_instance['hide-timeout'] ) ) );
233
			}
234
235 View Code Duplication
			if ( isset( $new_instance['consent-expiration'] ) ) {
236
				// Time can be a value between 1 and 365 days.
237
				$instance['consent-expiration'] = min( 365, max( 1, intval( $new_instance['consent-expiration'] ) ) );
238
			}
239
240
			if ( isset( $new_instance['customtext'] ) ) {
241
				$instance['customtext'] = mb_substr( wp_kses( $new_instance['customtext'], array() ), 0, 4096 );
242
			} else {
243
				$instance['text'] = $this->text_options[0];
244
			}
245
246
			if ( isset( $new_instance['policy-url'] ) ) {
247
				$instance['policy-url'] = 'custom' === $new_instance['policy-url']
248
					? 'custom'
249
					: 'default';
250
			} else {
251
				$instance['policy-url'] = $this->policy_url_options[0];
252
			}
253
254
			if ( 'custom' === $instance['policy-url'] && isset( $new_instance['custom-policy-url'] ) ) {
255
				$instance['custom-policy-url'] = esc_url( $new_instance['custom-policy-url'], array( 'http', 'https' ) );
256
257
				if ( strlen( $instance['custom-policy-url'] ) < 10 ) {
258
					unset( $instance['custom-policy-url'] );
259
					global $wp_customize;
260
					if ( ! isset( $wp_customize ) ) {
261
						$instance['policy-url'] = $this->policy_url_options[0];
262
					}
263
				}
264
			}
265
266 View Code Duplication
			if ( isset( $new_instance['policy-link-text'] ) ) {
267
				$instance['policy-link-text'] = trim( mb_substr( wp_kses( $new_instance['policy-link-text'], array() ), 0, 100 ) );
268
			}
269
270
			if ( empty( $instance['policy-link-text'] ) || $instance['policy-link-text'] == $defaults['policy-link-text'] ) {
271
				unset( $instance['policy-link-text'] );
272
			}
273
274 View Code Duplication
			if ( isset( $new_instance['button'] ) ) {
275
				$instance['button'] = trim( mb_substr( wp_kses( $new_instance['button'], array() ), 0, 100 ) );
276
			}
277
278
			if ( empty( $instance['button'] ) || $instance['button'] == $defaults['button'] ) {
279
				unset( $instance['button'] );
280
			}
281
282
			// Show the banner again if a setting has been changed.
283
			setcookie( self::$cookie_name, '', time() - 86400, '/' );
284
285
			return $instance;
286
		}
287
288
		/**
289
		 * Check if the value is allowed and not empty.
290
		 *
291
		 * @param  string $value Value to check.
292
		 * @param  array  $allowed Array of allowed values.
293
		 *
294
		 * @return string $value if pass the check or first value from allowed values.
295
		 */
296 View Code Duplication
		function filter_value( $value, $allowed = array() ) {
297
			$allowed = (array) $allowed;
298
			if ( empty( $value ) || ( ! empty( $allowed ) && ! in_array( $value, $allowed ) ) ) {
299
				$value = $allowed[0];
300
			}
301
			return $value;
302
		}
303
	}
304
305
	// Register Jetpack_EU_Cookie_Law_Widget widget.
306
	function jetpack_register_eu_cookie_law_widget() {
307
		register_widget( 'Jetpack_EU_Cookie_Law_Widget' );
308
	};
309
310
	add_action( 'widgets_init', 'jetpack_register_eu_cookie_law_widget' );
311
}
312