PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.9.1
Secure Custom Fields v6.9.1
6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / includes / fields / class-acf-field-wysiwyg.php
secure-custom-fields / includes / fields Last commit date
FlexibleContent 2 months ago class-acf-field-accordion.php 2 months ago class-acf-field-button-group.php 2 months ago class-acf-field-checkbox.php 3 days ago class-acf-field-clone.php 2 months ago class-acf-field-color_picker.php 2 months ago class-acf-field-date_picker.php 2 months ago class-acf-field-date_time_picker.php 2 months ago class-acf-field-email.php 2 months ago class-acf-field-file.php 2 months ago class-acf-field-flexible-content.php 1 week ago class-acf-field-gallery.php 3 weeks ago class-acf-field-google-map.php 2 months ago class-acf-field-group.php 2 months ago class-acf-field-icon_picker.php 7 months ago class-acf-field-image.php 2 months ago class-acf-field-link.php 2 months ago class-acf-field-message.php 1 year ago class-acf-field-nav-menu.php 1 week ago class-acf-field-number.php 2 months ago class-acf-field-oembed.php 3 weeks ago class-acf-field-output.php 1 year ago class-acf-field-page_link.php 3 weeks ago class-acf-field-password.php 2 months ago class-acf-field-post_object.php 3 weeks ago class-acf-field-radio.php 3 days ago class-acf-field-range.php 2 months ago class-acf-field-relationship.php 3 weeks ago class-acf-field-repeater.php 3 weeks ago class-acf-field-select.php 3 days ago class-acf-field-separator.php 1 year ago class-acf-field-tab.php 1 year ago class-acf-field-taxonomy.php 3 weeks ago class-acf-field-text.php 3 weeks ago class-acf-field-textarea.php 3 weeks ago class-acf-field-time_picker.php 2 months ago class-acf-field-true_false.php 2 months ago class-acf-field-url.php 3 weeks ago class-acf-field-user.php 3 weeks ago class-acf-field-wysiwyg.php 2 months ago class-acf-field.php 2 months ago class-acf-repeater-table.php 1 year ago index.php 1 year ago
class-acf-field-wysiwyg.php
429 lines
1 <?php
2
3 if ( ! class_exists( 'acf_field_wysiwyg' ) ) :
4
5 class acf_field_wysiwyg extends acf_field {
6
7
8 /**
9 * This function will setup the field type data
10 *
11 * @type function
12 * @date 5/03/2014
13 * @since ACF 5.0.0
14 *
15 * @param n/a
16 * @return n/a
17 */
18 function initialize() {
19
20 // vars
21 $this->name = 'wysiwyg';
22 $this->label = __( 'WYSIWYG Editor', 'secure-custom-fields' );
23 $this->category = 'content';
24 $this->description = __( 'Displays the WordPress WYSIWYG editor as seen in Posts and Pages allowing for a rich text-editing experience that also allows for multimedia content.', 'secure-custom-fields' ) . ' ' . __( 'We do not recommend using this field in ACF Blocks.', 'secure-custom-fields' );
25 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-wysiwyg.png';
26 $this->doc_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/wysiwyg/';
27 $this->tutorial_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/wysiwyg/wysiwyg-tutorial/';
28 $this->defaults = array(
29 'tabs' => 'all',
30 'toolbar' => 'full',
31 'media_upload' => 1,
32 'default_value' => '',
33 'delay' => 0,
34 );
35 $this->supports = array(
36 'escaping_html' => true,
37 );
38
39 // add acf_the_content filters
40 $this->add_filters();
41
42 // actions
43 add_action( 'acf/enqueue_uploader', array( $this, 'acf_enqueue_uploader' ) );
44 }
45
46
47 /**
48 * This function will add filters to 'acf_the_content'
49 *
50 * @type function
51 * @date 20/09/2016
52 * @since ACF 5.4.0
53 *
54 * @param n/a
55 * @return n/a
56 */
57 function add_filters() {
58
59 // WordPress 5.5 introduced new function for applying image tags.
60 $wp_filter_content_tags = function_exists( 'wp_filter_content_tags' ) ? 'wp_filter_content_tags' : 'wp_make_content_images_responsive';
61
62 // Mimic filters added to "the_content" in "wp-includes/default-filters.php".
63 add_filter( 'acf_the_content', 'capital_P_dangit', 11 );
64 // add_filter( 'acf_the_content', 'do_blocks', 9 ); Not yet supported.
65 add_filter( 'acf_the_content', 'wptexturize' );
66 add_filter( 'acf_the_content', 'convert_smilies', 20 );
67 add_filter( 'acf_the_content', 'wpautop' );
68 add_filter( 'acf_the_content', 'shortcode_unautop' );
69 // add_filter( 'acf_the_content', 'prepend_attachment' ); Causes double image on attachment page.
70 add_filter( 'acf_the_content', $wp_filter_content_tags );
71 add_filter( 'acf_the_content', 'do_shortcode', 11 );
72
73 // Mimic filters added to "the_content" in "wp-includes/class-wp-embed.php"
74 if ( isset( $GLOBALS['wp_embed'] ) ) {
75 add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 );
76 add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
77 }
78 }
79
80
81 /**
82 * This function will return an array of toolbars for the WYSIWYG field
83 *
84 * @type function
85 * @date 18/04/2014
86 * @since ACF 5.0.0
87 *
88 * @param n/a
89 * @return (array)
90 */
91 function get_toolbars() {
92
93 // vars
94 $editor_id = 'acf_content';
95 $toolbars = array();
96
97 // mce buttons (Full)
98 $mce_buttons = array( 'formatselect', 'bold', 'italic', 'bullist', 'numlist', 'blockquote', 'alignleft', 'aligncenter', 'alignright', 'link', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' );
99 $mce_buttons_2 = array( 'strikethrough', 'hr', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' );
100
101 // mce buttons (Basic)
102 $teeny_mce_buttons = array( 'bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'fullscreen' );
103
104 // Full
105 $toolbars['Full'] = array(
106 1 => apply_filters( 'mce_buttons', $mce_buttons, $editor_id ),
107 2 => apply_filters( 'mce_buttons_2', $mce_buttons_2, $editor_id ),
108 3 => apply_filters( 'mce_buttons_3', array(), $editor_id ),
109 4 => apply_filters( 'mce_buttons_4', array(), $editor_id ),
110 );
111
112 // Basic
113 $toolbars['Basic'] = array(
114 1 => apply_filters( 'teeny_mce_buttons', $teeny_mce_buttons, $editor_id ),
115 );
116
117 // Filter for 3rd party
118 $toolbars = apply_filters( 'acf/fields/wysiwyg/toolbars', $toolbars );
119
120 // return
121 return $toolbars;
122 }
123
124
125 /**
126 * Registers toolbars data for the WYSIWYG field.
127 *
128 * @type function
129 * @date 16/12/2015
130 * @since ACF 5.3.2
131 *
132 * @return void
133 */
134 function acf_enqueue_uploader() {
135
136 // vars
137 $data = array();
138 $toolbars = $this->get_toolbars();
139
140 // loop
141 if ( $toolbars ) {
142 foreach ( $toolbars as $label => $rows ) {
143
144 // vars
145 $key = $label;
146 $key = sanitize_title( $key );
147 $key = str_replace( '-', '_', $key );
148
149 // append
150 $data[ $key ] = array();
151
152 if ( $rows ) {
153 foreach ( $rows as $i => $row ) {
154 $data[ $key ][ $i ] = implode( ',', $row );
155 }
156 }
157 }
158 }
159
160 // localize
161 acf_localize_data(
162 array(
163 'toolbars' => $data,
164 )
165 );
166 }
167
168 /**
169 * Create the HTML interface for your field
170 *
171 * @param array $field An array holding all the field's data
172 *
173 * @type action
174 * @since ACF 3.6
175 * @date 23/01/13
176 */
177 function render_field( $field ) {
178
179 // enqueue
180 acf_enqueue_uploader();
181
182 // vars
183 $id = uniqid( 'acf-editor-' );
184 $default_editor = 'html';
185 $show_tabs = true;
186
187 // get height
188 $height = acf_get_user_setting( 'wysiwyg_height', 300 );
189 $height = max( $height, 300 ); // minimum height is 300
190
191 // detect mode
192 if ( ! user_can_richedit() ) {
193 $show_tabs = false;
194 } elseif ( $field['tabs'] == 'visual' ) {
195
196 // case: visual tab only
197 $default_editor = 'tinymce';
198 $show_tabs = false;
199 } elseif ( $field['tabs'] == 'text' ) {
200
201 // case: text tab only
202 $show_tabs = false;
203 } elseif ( wp_default_editor() == 'tinymce' ) {
204
205 // case: both tabs
206 $default_editor = 'tinymce';
207 }
208
209 // must be logged in to upload
210 if ( ! current_user_can( 'upload_files' ) ) {
211 $field['media_upload'] = 0;
212 }
213
214 // mode
215 $switch_class = ( $default_editor === 'html' ) ? 'html-active' : 'tmce-active';
216
217 // filter
218 add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 );
219
220 $field['value'] = is_string( $field['value'] ) ? $field['value'] : '';
221 $field['value'] = apply_filters( 'acf_the_editor_content', $field['value'], $default_editor );
222
223 // attr
224 $wrap = array(
225 'id' => 'wp-' . $id . '-wrap',
226 'class' => 'acf-editor-wrap wp-core-ui wp-editor-wrap ' . $switch_class,
227 'data-toolbar' => $field['toolbar'],
228 );
229
230 // delay
231 if ( $field['delay'] ) {
232 $wrap['class'] .= ' delay';
233 }
234
235 // vars
236 $textarea = acf_get_textarea_input(
237 array(
238 'id' => $id,
239 'class' => 'wp-editor-area',
240 'name' => $field['name'],
241 'style' => $height ? "height:{$height}px;" : '',
242 'value' => '%s',
243 )
244 );
245
246 ?>
247 <div <?php echo acf_esc_attrs( $wrap ); ?>>
248 <div id="wp-<?php echo esc_attr( $id ); ?>-editor-tools" class="wp-editor-tools hide-if-no-js">
249 <?php if ( $field['media_upload'] ) : ?>
250 <div id="wp-<?php echo esc_attr( $id ); ?>-media-buttons" class="wp-media-buttons">
251 <?php
252 if ( ! function_exists( 'media_buttons' ) ) {
253 require ABSPATH . 'wp-admin/includes/media.php';
254 }
255 do_action( 'media_buttons', $id );
256 ?>
257 </div>
258 <?php endif; ?>
259 <?php if ( user_can_richedit() && $show_tabs ) : ?>
260 <div class="wp-editor-tabs">
261 <button id="<?php echo esc_attr( $id ); ?>-tmce" class="wp-switch-editor switch-tmce" data-wp-editor-id="<?php echo esc_attr( $id ); ?>" type="button"><?php esc_html_e( 'Visual', 'secure-custom-fields' ); ?></button>
262 <button id="<?php echo esc_attr( $id ); ?>-html" class="wp-switch-editor switch-html" data-wp-editor-id="<?php echo esc_attr( $id ); ?>" type="button"><?php echo esc_html_x( 'Text', 'Name for the Text editor tab (formerly HTML)', 'secure-custom-fields' ); ?></button>
263 </div>
264 <?php endif; ?>
265 </div>
266 <div id="wp-<?php echo esc_attr( $id ); ?>-editor-container" class="wp-editor-container">
267 <?php if ( $field['delay'] ) : ?>
268 <div class="acf-editor-toolbar"><?php esc_html_e( 'Click to initialize TinyMCE', 'secure-custom-fields' ); ?></div>
269 <?php endif; ?>
270 <?php printf( $textarea, $field['value'] ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped by format_for_editor(). ?>
271 </div>
272 </div>
273 <?php
274 }
275
276
277 /**
278 * Create extra options for your field. This is rendered when editing a field.
279 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
280 *
281 * @type action
282 * @since ACF 3.6
283 * @date 23/01/13
284 *
285 * @param $field - an array holding all the field's data
286 */
287 function render_field_settings( $field ) {
288 acf_render_field_setting(
289 $field,
290 array(
291 'label' => __( 'Default Value', 'secure-custom-fields' ),
292 'instructions' => __( 'Appears when creating a new post', 'secure-custom-fields' ),
293 'type' => 'textarea',
294 'name' => 'default_value',
295 )
296 );
297 }
298
299 /**
300 * Renders the field settings used in the "Presentation" tab.
301 *
302 * @since ACF 6.0
303 *
304 * @param array $field The field settings array.
305 * @return void
306 */
307 function render_field_presentation_settings( $field ) {
308 $toolbars = $this->get_toolbars();
309 $choices = array();
310
311 if ( ! empty( $toolbars ) ) {
312 foreach ( $toolbars as $k => $v ) {
313 $label = $k;
314 $name = sanitize_title( $label );
315 $name = str_replace( '-', '_', $name );
316
317 $choices[ $name ] = $label;
318 }
319 }
320
321 acf_render_field_setting(
322 $field,
323 array(
324 'label' => __( 'Tabs', 'secure-custom-fields' ),
325 'instructions' => '',
326 'type' => 'select',
327 'name' => 'tabs',
328 'choices' => array(
329 'all' => __( 'Visual & Text', 'secure-custom-fields' ),
330 'visual' => __( 'Visual Only', 'secure-custom-fields' ),
331 'text' => __( 'Text Only', 'secure-custom-fields' ),
332 ),
333 )
334 );
335
336 acf_render_field_setting(
337 $field,
338 array(
339 'label' => __( 'Toolbar', 'secure-custom-fields' ),
340 'instructions' => '',
341 'type' => 'select',
342 'name' => 'toolbar',
343 'choices' => $choices,
344 'conditions' => array(
345 'field' => 'tabs',
346 'operator' => '!=',
347 'value' => 'text',
348 ),
349 )
350 );
351
352 acf_render_field_setting(
353 $field,
354 array(
355 'label' => __( 'Show Media Upload Buttons', 'secure-custom-fields' ),
356 'instructions' => '',
357 'name' => 'media_upload',
358 'type' => 'true_false',
359 'ui' => 1,
360 )
361 );
362
363 acf_render_field_setting(
364 $field,
365 array(
366 'label' => __( 'Delay Initialization', 'secure-custom-fields' ),
367 'instructions' => __( 'TinyMCE will not be initialized until field is clicked', 'secure-custom-fields' ),
368 'name' => 'delay',
369 'type' => 'true_false',
370 'ui' => 1,
371 'conditions' => array(
372 'field' => 'tabs',
373 'operator' => '!=',
374 'value' => 'text',
375 ),
376 )
377 );
378 }
379 /**
380 * This filter is applied to the $value after it is loaded from the db, and before it is returned to the template
381 *
382 * @type filter
383 * @since ACF 3.6
384 *
385 * @param mixed $value The value which was loaded from the database.
386 * @param mixed $post_id The $post_id from which the value was loaded.
387 * @param array $field The field array holding all the field options.
388 * @param boolean $escape_html Should the field return a HTML safe formatted value.
389 * @return mixed $value The modified value
390 */
391 public function format_value( $value, $post_id, $field, $escape_html ) {
392 // Bail early if no value or not a string.
393 if ( empty( $value ) || ! is_string( $value ) ) {
394 return $value;
395 }
396
397 if ( $escape_html ) {
398 add_filter( 'acf_the_content', 'acf_esc_html', 1 );
399 }
400
401 $value = apply_filters( 'acf_the_content', $value );
402
403 if ( $escape_html ) {
404 remove_filter( 'acf_the_content', 'acf_esc_html', 1 );
405 }
406
407 // Follow the_content function in /wp-includes/post-template.php
408 return str_replace( ']]>', ']]&gt;', $value );
409 }
410
411 /**
412 * Returns an array of JSON-LD Property output types that are supported by this field type.
413 *
414 * @since 6.8
415 *
416 * @return string[]
417 */
418 public function get_jsonld_output_types(): array {
419 return array( 'Text' );
420 }
421 }
422
423
424 // initialize
425 acf_register_field_type( 'acf_field_wysiwyg' );
426 endif; // class_exists check
427
428 ?>
429