acf_field_wysiwyg   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 445
Duplicated Lines 2.47 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
dl 11
loc 445
rs 10
c 0
b 0
f 0
wmc 27
lcom 0
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 46 3
B get_toolbars() 0 68 2
B input_admin_footer_js() 0 45 5
F render_field() 0 104 12
B render_field_settings() 11 66 3
A format_value() 0 20 2

How to fix   Duplicated Code   

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:

1
<?php
2
3
/*
4
*  ACF WYSIWYG Field Class
5
*
6
*  All the logic for this field type
7
*
8
*  @class 		acf_field_wysiwyg
9
*  @extends		acf_field
10
*  @package		ACF
11
*  @subpackage	Fields
12
*/
13
14
if( ! class_exists('acf_field_wysiwyg') ) :
15
16
class acf_field_wysiwyg extends acf_field {
17
	
18
	var $exists = 0;
19
	
20
	/*
21
	*  __construct
22
	*
23
	*  This function will setup the field type data
24
	*
25
	*  @type	function
26
	*  @date	5/03/2014
27
	*  @since	5.0.0
28
	*
29
	*  @param	n/a
30
	*  @return	n/a
31
	*/
0 ignored issues
show
Documentation introduced by
The doc-type n/a could not be parsed: Unknown type name "n/a" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
32
	
33
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
34
		
35
		// vars
36
		$this->name = 'wysiwyg';
37
		$this->label = __("Wysiwyg Editor",'acf');
0 ignored issues
show
Bug introduced by
The property label does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
38
		$this->category = 'content';
39
		$this->defaults = array(
40
			'tabs'			=> 'all',
41
			'toolbar'		=> 'full',
42
			'media_upload' 	=> 1,
43
			'default_value'	=> '',
44
		);
45
    	
46
    	
47
    	// Create an acf version of the_content filter (acf_the_content)
48
		if(	!empty($GLOBALS['wp_embed']) ) {
49
		
50
			add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 );
51
			add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
52
			
53
		}
54
		
55
		add_filter( 'acf_the_content', 'capital_P_dangit', 11 );
56
		add_filter( 'acf_the_content', 'wptexturize' );
57
		add_filter( 'acf_the_content', 'convert_smilies' );
58
		add_filter( 'acf_the_content', 'convert_chars' ); // not found in WP 4.4
59
		add_filter( 'acf_the_content', 'wpautop' );
60
		add_filter( 'acf_the_content', 'shortcode_unautop' );
61
		//add_filter( 'acf_the_content', 'prepend_attachment' ); should only be for the_content (causes double image on attachment page)
62
		if( function_exists('wp_make_content_images_responsive') ) {
63
			
64
			add_filter( 'acf_the_content', 'wp_make_content_images_responsive' ); // added in WP 4.4
65
			
66
		}
67
		
68
		add_filter( 'acf_the_content', 'do_shortcode', 11);
69
		
70
71
		// actions
72
		add_action('acf/input/admin_footer_js', 	array($this, 'input_admin_footer_js'));
73
		
74
		
75
		// do not delete!
76
    	parent::__construct();
77
    	
78
	}
79
	
80
	
81
	/*
82
	*  get_toolbars
83
	*
84
	*  This function will return an array of toolbars for the WYSIWYG field
85
	*
86
	*  @type	function
87
	*  @date	18/04/2014
88
	*  @since	5.0.0
89
	*
90
	*  @param	n/a
91
	*  @return	(array)
92
	*/
93
	
94
   	function get_toolbars() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
95
   		
96
   		// global
97
   		global $wp_version;
98
   		
99
   		
100
   		// vars
101
   		$toolbars = array();
102
   		$editor_id = 'acf_content';
103
   		
104
   		
105
   		if( version_compare($wp_version, '3.9', '>=' ) ) {
106
   		
107
   			// Full
108
	   		$toolbars['Full'] = array(
109
	   			
110
	   			1 => apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ), $editor_id),
111
	   			
112
	   			2 => apply_filters('mce_buttons_2', array( 'formatselect', 'underline', 'alignjustify', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ), $editor_id),
113
	   			
114
	   			3 => apply_filters('mce_buttons_3', array(), $editor_id),
115
	   			
116
	   			4 => apply_filters('mce_buttons_4', array(), $editor_id),
117
	   			
118
	   		);
119
	   		
120
	   		
121
	   		// Basic
122
	   		$toolbars['Basic'] = array(
123
	   			
124
	   			1 => apply_filters('teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id),
125
	   			
126
	   		);
127
	   		  		
128
   		} else {
129
	   		
130
	   		// Full
131
	   		$toolbars['Full'] = array(
132
	   			
133
	   			1 => apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'justifyleft', 'justifycenter', 'justifyright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ), $editor_id),
134
	   			
135
	   			2 => apply_filters('mce_buttons_2', array( 'formatselect', 'underline', 'justifyfull', 'forecolor', 'pastetext', 'pasteword', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ), $editor_id),
136
	   			
137
	   			3 => apply_filters('mce_buttons_3', array(), $editor_id),
138
	   			
139
	   			4 => apply_filters('mce_buttons_4', array(), $editor_id),
140
	   			
141
	   		);
142
143
	   		
144
	   		// Basic
145
	   		$toolbars['Basic'] = array(
146
	   			
147
	   			1 => apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id ),
148
	   			
149
	   		);
150
	   		
151
   		}
152
   		
153
   		
154
   		// Filter for 3rd party
155
   		$toolbars = apply_filters( 'acf/fields/wysiwyg/toolbars', $toolbars );
156
   		
157
   		
158
   		// return
159
	   	return $toolbars;
160
	   	
161
   	}
162
   	
163
   	
164
   	/*
165
   	*  input_admin_footer_js
166
   	*
167
   	*  description
168
   	*
169
   	*  @type	function
170
   	*  @date	6/03/2014
171
   	*  @since	5.0.0
172
   	*
173
   	*  @param	$post_id (int)
174
   	*  @return	$post_id (int)
175
   	*/
0 ignored issues
show
Documentation introduced by
The doc-type $post_id could not be parsed: Unknown type name "$post_id" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
176
   	
177
   	function input_admin_footer_js() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
178
	   	
179
	   	// vars
180
		$json = array();
181
		$toolbars = $this->get_toolbars();
182
183
		
184
		// bail ealry if no toolbars
185
		if( empty($toolbars) ) {
186
			
187
			return;
188
			
189
		}
190
		
191
			
192
		// loop through toolbars
193
		foreach( $toolbars as $label => $rows ) {
194
			
195
			// vars
196
			$label = sanitize_title( $label );
197
			$label = str_replace('-', '_', $label);
198
			
199
			
200
			// append to $json
201
			$json[ $label ] = array();
202
			
203
			
204
			// convert to strings
205
			if( !empty($rows) ) {
206
				
207
				foreach( $rows as $i => $row ) { 
208
					
209
					$json[ $label ][ $i ] = implode(',', $row);
210
					
211
				}
212
				
213
			}
214
			
215
		}
216
		
217
		
218
		?>acf.fields.wysiwyg.toolbars = <?php echo json_encode($json); ?>;
219
	<?php
220
	
221
   	}
222
   	
223
   	
224
   	/*
225
	*  render_field()
226
	*
227
	*  Create the HTML interface for your field
228
	*
229
	*  @param	$field - an array holding all the field's data
230
	*
231
	*  @type	action
232
	*  @since	3.6
233
	*  @date	23/01/13
234
	*/
235
	
236
	function render_field( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
237
		
238
		// global
239
   		global $wp_version;
240
   		
241
   		
242
		// enqueue
243
		acf_enqueue_uploader();
244
		
245
		
246
		// vars
247
		$id = uniqid('acf-editor-');
248
		$default_editor = 'html';
249
		$show_tabs = true;
250
		$button = '';
0 ignored issues
show
Unused Code introduced by
$button is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
251
		
252
		
253
		// get height
254
		$height = acf_get_user_setting('wysiwyg_height', 300);
0 ignored issues
show
Documentation introduced by
300 is of type integer, but the function expects a boolean.

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...
255
		$height = max( $height, 300 ); // minimum height is 300
256
		
257
		
258
		// detect mode
259
		if( $field['tabs'] == 'visual' ) {
260
			
261
			// case: visual tab only
262
			$default_editor = 'tinymce';
263
			$show_tabs = false;
264
			
265
		} elseif( $field['tabs'] == 'text' ) {
266
			
267
			// case: text tab only
268
			$show_tabs = false;
269
			
270
		} elseif( wp_default_editor() == 'tinymce' ) {
271
			
272
			// case: both tabs
273
			$default_editor = 'tinymce';
274
			
275
		}
276
		
277
		
278
		// must be logged in tp upload
279
		if( !current_user_can('upload_files') ) {
280
			
281
			$field['media_upload'] = 0;
282
			
283
		}
284
		
285
		
286
		// mode
287
		$switch_class = ($default_editor === 'html') ? 'html-active' : 'tmce-active';
288
		
289
		
290
		// filter value for editor
291
		remove_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 );
292
		remove_filter( 'acf_the_editor_content', 'wp_htmledit_pre', 10, 1 );
293
		remove_filter( 'acf_the_editor_content', 'wp_richedit_pre', 10, 1 );
294
		
295
		
296
		// WP 4.3
297
		if( version_compare($wp_version, '4.3', '>=' ) ) {
298
			
299
			add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 );
300
			
301
			$button = 'data-wp-editor-id="' . $id . '"';
302
			
303
		// WP < 4.3
304
		} else {
305
			
306
			$function = ($default_editor === 'html') ? 'wp_htmledit_pre' : 'wp_richedit_pre';
307
			
308
			add_filter('acf_the_editor_content', $function, 10, 1);
309
			
310
			$button = 'onclick="switchEditors.switchto(this);"';
311
			
312
		}
313
		
314
		
315
		// filter
316
		$field['value'] = apply_filters( 'acf_the_editor_content', $field['value'], $default_editor );
317
		
318
		?>
319
		<div id="wp-<?php echo $id; ?>-wrap" class="acf-editor-wrap wp-core-ui wp-editor-wrap <?php echo $switch_class; ?>" data-toolbar="<?php echo $field['toolbar']; ?>" data-upload="<?php echo $field['media_upload']; ?>">
320
			<div id="wp-<?php echo $id; ?>-editor-tools" class="wp-editor-tools hide-if-no-js">
321
				<?php if( $field['media_upload'] ): ?>
322
				<div id="wp-<?php echo $id; ?>-media-buttons" class="wp-media-buttons">
323
					<?php do_action( 'media_buttons', $id ); ?>
324
				</div>
325
				<?php endif; ?>
326
				<?php if( user_can_richedit() && $show_tabs ): ?>
327
					<div class="wp-editor-tabs">
328
						<button id="<?php echo $id; ?>-tmce" class="wp-switch-editor switch-tmce" <?php echo  $button; ?> type="button"><?php echo __('Visual', 'acf'); ?></button>
329
						<button id="<?php echo $id; ?>-html" class="wp-switch-editor switch-html" <?php echo  $button; ?> type="button"><?php echo _x( 'Text', 'Name for the Text editor tab (formerly HTML)', 'acf' ); ?></button>
330
					</div>
331
				<?php endif; ?>
332
			</div>
333
			<div id="wp-<?php echo $id; ?>-editor-container" class="wp-editor-container">
334
				<textarea id="<?php echo $id; ?>" class="wp-editor-area" name="<?php echo $field['name']; ?>" <?php if($height): ?>style="height:<?php echo $height; ?>px;"<?php endif; ?>><?php echo $field['value']; ?></textarea>
335
			</div>
336
		</div>
337
		<?php
338
				
339
	}
340
	
341
	
342
	/*
343
	*  render_field_settings()
344
	*
345
	*  Create extra options for your field. This is rendered when editing a field.
346
	*  The value of $field['name'] can be used (like bellow) to save extra data to the $field
347
	*
348
	*  @type	action
349
	*  @since	3.6
350
	*  @date	23/01/13
351
	*
352
	*  @param	$field	- an array holding all the field's data
353
	*/
354
	
355
	function render_field_settings( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
356
		
357
		// vars
358
		$toolbars = $this->get_toolbars();
359
		$choices = array();
360
		
361 View Code Duplication
		if( !empty($toolbars) ) {
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...
362
		
363
			foreach( $toolbars as $k => $v ) {
364
				
365
				$label = $k;
366
				$name = sanitize_title( $label );
367
				$name = str_replace('-', '_', $name);
368
				
369
				$choices[ $name ] = $label;
370
			}
371
		}
372
		
373
		
374
		// default_value
375
		acf_render_field_setting( $field, array(
376
			'label'			=> __('Default Value','acf'),
377
			'instructions'	=> __('Appears when creating a new post','acf'),
378
			'type'			=> 'textarea',
379
			'name'			=> 'default_value',
380
		));
381
		
382
		
383
		// tabs
384
		acf_render_field_setting( $field, array(
385
			'label'			=> __('Tabs','acf'),
386
			'instructions'	=> '',
387
			'type'			=> 'select',
388
			'name'			=> 'tabs',
389
			'choices'		=> array(
390
				'all'			=>	__("Visual & Text",'acf'),
391
				'visual'		=>	__("Visual Only",'acf'),
392
				'text'			=>	__("Text Only",'acf'),
393
			)
394
		));
395
		
396
		
397
		// toolbar
398
		acf_render_field_setting( $field, array(
399
			'label'			=> __('Toolbar','acf'),
400
			'instructions'	=> '',
401
			'type'			=> 'select',
402
			'name'			=> 'toolbar',
403
			'choices'		=> $choices
404
		));
405
		
406
		
407
		// media_upload
408
		acf_render_field_setting( $field, array(
409
			'label'			=> __('Show Media Upload Buttons?','acf'),
410
			'instructions'	=> '',
411
			'type'			=> 'radio',
412
			'name'			=> 'media_upload',
413
			'layout'		=> 'horizontal',
414
			'choices'		=> array(
415
				1				=>	__("Yes",'acf'),
416
				0				=>	__("No",'acf'),
417
			)
418
		));
419
420
	}
421
		
422
	
423
	/*
424
	*  format_value()
425
	*
426
	*  This filter is appied to the $value after it is loaded from the db and before it is returned to the template
427
	*
428
	*  @type	filter
429
	*  @since	3.6
430
	*  @date	23/01/13
431
	*
432
	*  @param	$value (mixed) the value which was loaded from the database
433
	*  @param	$post_id (mixed) the $post_id from which the value was loaded
434
	*  @param	$field (array) the field array holding all the field options
435
	*
436
	*  @return	$value (mixed) the modified value
437
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
438
	
439
	function format_value( $value, $post_id, $field ) {
0 ignored issues
show
Unused Code introduced by
The parameter $post_id 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...
Unused Code introduced by
The parameter $field 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...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
440
		
441
		// bail early if no value
442
		if( empty($value) ) {
443
			
444
			return $value;
445
		
446
		}
447
		
448
		
449
		// apply filters
450
		$value = apply_filters( 'acf_the_content', $value );
451
		
452
		
453
		// follow the_content function in /wp-includes/post-template.php
454
		$value = str_replace(']]>', ']]&gt;', $value);
455
		
456
	
457
		return $value;
458
	}
459
	
460
}
461
462
new acf_field_wysiwyg();
463
464
endif;
465
466
?>
467