PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.8.23.4
Pods – Custom Content Types and Fields v2.8.23.4
2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / classes / fields / wysiwyg.php
pods / classes / fields Last commit date
avatar.php 2 weeks ago boolean.php 2 weeks ago code.php 2 weeks ago color.php 2 weeks ago comment.php 2 weeks ago currency.php 2 weeks ago date.php 2 weeks ago datetime.php 2 weeks ago email.php 2 weeks ago file.php 2 weeks ago heading.php 2 weeks ago html.php 2 weeks ago link.php 2 weeks ago number.php 2 weeks ago oembed.php 2 weeks ago paragraph.php 2 weeks ago password.php 2 weeks ago phone.php 2 weeks ago pick.php 2 weeks ago slug.php 2 weeks ago taxonomy.php 2 weeks ago text.php 2 weeks ago time.php 2 weeks ago website.php 2 weeks ago wysiwyg.php 2 weeks ago
wysiwyg.php
384 lines
1 <?php
2
3 /**
4 * @package Pods\Fields
5 */
6 class PodsField_WYSIWYG extends PodsField {
7
8 /**
9 * {@inheritdoc}
10 */
11 public static $group = 'Paragraph';
12
13 /**
14 * {@inheritdoc}
15 */
16 public static $type = 'wysiwyg';
17
18 /**
19 * {@inheritdoc}
20 */
21 public static $label = 'WYSIWYG (Visual Editor)';
22
23 /**
24 * {@inheritdoc}
25 */
26 public static $prepare = '%s';
27
28 /**
29 * {@inheritdoc}
30 */
31 public function setup() {
32
33 static::$group = __( 'Paragraph', 'pods' );
34 static::$label = __( 'WYSIWYG (Visual Editor)', 'pods' );
35 }
36
37 /**
38 * {@inheritdoc}
39 */
40 public function options() {
41
42 $options = array(
43 static::$type . '_repeatable' => array(
44 'label' => __( 'Repeatable Field', 'pods' ),
45 'default' => 0,
46 'type' => 'boolean',
47 'help' => __( 'Making a field repeatable will add controls next to the field which allows users to Add/Remove/Reorder additional values. These values are saved in the database as an array, so searching and filtering by them may require further adjustments".', 'pods' ),
48 'boolean_yes_label' => '',
49 'dependency' => true,
50 'developer_mode' => true,
51 ),
52 static::$type . '_editor' => array(
53 'label' => __( 'Editor', 'pods' ),
54 'default' => 'tinymce',
55 'type' => 'pick',
56 'data' => apply_filters(
57 'pods_form_ui_field_wysiwyg_editors', array(
58 'tinymce' => __( 'TinyMCE (WP Default)', 'pods' ),
59 'quill' => __( 'Quill Editor (Limited line break functionality)', 'pods' ),
60 'cleditor' => __( 'CLEditor (No longer available, now using Quill Editor)', 'pods' ),
61 )
62 ),
63 'pick_show_select_text' => 0,
64 'dependency' => true,
65 ),
66 'editor_options' => array(
67 'label' => __( 'Editor Options', 'pods' ),
68 'type' => 'boolean_group',
69 'depends-on' => array( static::$type . '_editor' => 'tinymce' ),
70 'boolean_group' => array(
71 static::$type . '_media_buttons' => array(
72 'label' => __( 'Enable Media Buttons', 'pods' ),
73 'default' => 1,
74 'type' => 'boolean',
75 ),
76 ),
77 ),
78 static::$type . '_editor_height' => array(
79 'label' => __( 'Editor Height', 'pods' ),
80 'help' => __( 'Height in pixels', 'pods' ),
81 'default' => '',
82 'type' => 'number',
83 'depends-on' => array( static::$type . '_editor' => 'tinymce' ),
84 'number_decimals' => 0,
85 ),
86 'output_options' => array(
87 'label' => __( 'Output Options', 'pods' ),
88 'type' => 'boolean_group',
89 'boolean_group' => array(
90 static::$type . '_trim' => array(
91 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ),
92 'default' => 1,
93 'type' => 'boolean',
94 'dependency' => true,
95 ),
96 static::$type . '_oembed' => array(
97 'label' => __( 'Enable oEmbed', 'pods' ),
98 'default' => 0,
99 'type' => 'boolean',
100 'help' => array(
101 __( 'Embed videos, images, tweets, and other content.', 'pods' ),
102 'https://wordpress.org/support/article/embeds/',
103 ),
104 ),
105 static::$type . '_wptexturize' => array(
106 'label' => __( 'Enable wptexturize', 'pods' ),
107 'default' => 1,
108 'type' => 'boolean',
109 'help' => array(
110 __( 'Transforms less-beautiful text characters into stylized equivalents.', 'pods' ),
111 'https://developer.wordpress.org/reference/functions/wptexturize/',
112 ),
113 ),
114 static::$type . '_convert_chars' => array(
115 'label' => __( 'Enable convert_chars', 'pods' ),
116 'default' => 1,
117 'type' => 'boolean',
118 'help' => array(
119 __( 'Converts text into valid XHTML and Unicode', 'pods' ),
120 'https://developer.wordpress.org/reference/functions/convert_chars/',
121 ),
122 ),
123 static::$type . '_wpautop' => array(
124 'label' => __( 'Enable wpautop', 'pods' ),
125 'default' => 1,
126 'type' => 'boolean',
127 'help' => array(
128 __( 'Changes double line-breaks in the text into HTML paragraphs', 'pods' ),
129 'https://developer.wordpress.org/reference/functions/wpautop/',
130 ),
131 ),
132 static::$type . '_allow_shortcode' => array(
133 'label' => __( 'Allow Shortcodes', 'pods' ),
134 'default' => 0,
135 'type' => 'boolean',
136 'dependency' => true,
137 'help' => array(
138 __( 'Embed [shortcodes] that help transform your static content into dynamic content.', 'pods' ),
139 'https://codex.wordpress.org/Shortcode_API',
140 ),
141 ),
142 ),
143 ),
144 static::$type . '_allowed_html_tags' => array(
145 'label' => __( 'Allowed HTML Tags', 'pods' ),
146 'default' => '',
147 'type' => 'text',
148 'help' => __( 'Format: strong em a ul ol li b i', 'pods' ),
149 ),
150 );
151
152 if ( function_exists( 'Markdown' ) ) {
153 $options['output_options']['boolean_group'][ static::$type . '_allow_markdown' ] = array(
154 'label' => __( 'Allow Markdown Syntax', 'pods' ),
155 'default' => 0,
156 'type' => 'boolean',
157 );
158 }
159
160 return $options;
161 }
162
163 /**
164 * {@inheritdoc}
165 */
166 public function schema( $options = null ) {
167
168 $schema = 'LONGTEXT';
169
170 return $schema;
171 }
172
173 /**
174 * {@inheritdoc}
175 */
176 public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
177 $value = $this->strip_html( $value, $options );
178 $value = $this->strip_shortcodes( $value, $options );
179 $value = $this->trim_whitespace( $value, $options );
180
181 if ( 1 === (int) pods_v( static::$type . '_oembed', $options, 0 ) ) {
182 $post_temp = false;
183
184 // Workaround for WP_Embed since it needs a $post to work from
185 if ( 'post_type' === pods_v( 'type', $pod ) && 0 < $id && ( ! isset( $GLOBALS['post'] ) || empty( $GLOBALS['post'] ) ) ) {
186 $post_temp = true;
187
188 // @codingStandardsIgnoreLine
189 $GLOBALS['post'] = get_post( $id );
190 }
191
192 /**
193 * @var $embed WP_Embed
194 */
195 $embed = $GLOBALS['wp_embed'];
196 $value = $embed->run_shortcode( $value );
197 $value = $embed->autoembed( $value );
198
199 // Cleanup after ourselves
200 if ( $post_temp ) {
201 // @codingStandardsIgnoreLine
202 $GLOBALS['post'] = null;
203 }
204 }//end if
205
206 if ( 1 === (int) pods_v( static::$type . '_wptexturize', $options, 1 ) ) {
207 $value = wptexturize( $value );
208 }
209
210 if ( 1 === (int) pods_v( static::$type . '_convert_chars', $options, 1 ) ) {
211 $value = convert_chars( $value );
212 }
213
214 if ( 1 === (int) pods_v( static::$type . '_wpautop', $options, 1 ) ) {
215 $value = wpautop( $value );
216 }
217
218 if ( 1 === (int) pods_v( static::$type . '_allow_shortcode', $options, 0 ) ) {
219 if ( 1 === (int) pods_v( static::$type . '_wpautop', $options, 1 ) ) {
220 $value = shortcode_unautop( $value );
221 }
222
223 $value = do_shortcode( $value );
224 }
225
226 if ( function_exists( 'Markdown' ) && 1 === (int) pods_v( static::$type . '_allow_markdown', $options ) ) {
227 $value = Markdown( $value );
228 }
229
230 return $value;
231 }
232
233 /**
234 * {@inheritdoc}
235 */
236 public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
237
238 $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
239 $form_field_type = PodsForm::$field_type;
240
241 if ( is_array( $value ) ) {
242 $value = implode( "\n", $value );
243 }
244
245 // Normalize the line breaks for React.
246 $value = str_replace( "\r\n", "\n", $value );
247 $value = str_replace( "\r", "\n", $value );
248
249 if ( isset( $options['name'] ) && ! pods_permission( $options ) ) {
250 if ( pods_v( 'read_only', $options, false ) ) {
251 $options['readonly'] = true;
252
253 $field_type = 'textarea';
254 } else {
255 return;
256 }
257 } elseif ( ! pods_has_permissions( $options ) && pods_v( 'read_only', $options, false ) ) {
258 $options['readonly'] = true;
259
260 $field_type = 'textarea';
261 } elseif ( 'tinymce' === pods_v( static::$type . '_editor', $options ) ) {
262 $field_type = 'tinymce';
263
264 // Enforce boolean.
265 $options[ static::$type . '_media_buttons' ] = filter_var( pods_v( static::$type . '_editor', $options, true ), FILTER_VALIDATE_BOOLEAN );
266
267 // Set up default editor.
268 // @todo Support this properly in React, which will be a challenge.
269 $options[ static::$type . '_default_editor' ] = pods_v( static::$type . '_default_editor', $options, wp_default_editor(), true );
270
271 if ( in_array( $options[ static::$type . '_default_editor' ], [ 'html', 'tinymce' ], true ) ) {
272 $options[ static::$type . '_default_editor' ] = 'tinymce';
273 }
274
275 wp_tinymce_inline_scripts();
276 wp_enqueue_editor();
277
278 $settings = [];
279 $settings['textarea_name'] = $name;
280 $settings['media_buttons'] = false;
281
282 if ( ! ( defined( 'PODS_DISABLE_FILE_UPLOAD' ) && true === PODS_DISABLE_FILE_UPLOAD ) && ! ( defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) && is_bool( PODS_UPLOAD_REQUIRE_LOGIN ) && true === PODS_UPLOAD_REQUIRE_LOGIN && ! is_user_logged_in() ) && ! ( defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) && ! is_bool( PODS_UPLOAD_REQUIRE_LOGIN ) && ( ! is_user_logged_in() || ! current_user_can( PODS_UPLOAD_REQUIRE_LOGIN ) ) ) ) {
283 $settings['media_buttons'] = (boolean) pods_v( static::$type . '_media_buttons', $options, true );
284 }
285
286 $editor_height = (int) pods_v( static::$type . '_editor_height', $options, false );
287
288 if ( $editor_height ) {
289 $settings['editor_height'] = $editor_height;
290 }
291
292 if ( ! empty( $options[ static::$type . '_tinymce_settings' ] ) ) {
293 $settings = array_merge( $settings, $options[ static::$type . '_tinymce_settings' ] );
294 }
295
296 // WP will handle the scripting needed, but we won't output the textarea here.
297 ob_start();
298 wp_editor( $value, '_pods_dfv_' . $name, $settings );
299 $unused_output = ob_get_clean();
300
301 // Workaround because the above already outputs the style we need.
302 $styles = wp_styles();
303
304 $found_editor_buttons = array_search( 'editor-buttons', $styles->done, true );
305
306 if ( false !== $found_editor_buttons ) {
307 unset( $styles->done[ $found_editor_buttons ] );
308 }
309
310 wp_print_styles( 'editor-buttons' );
311 } elseif ( 'quill' === pods_v( static::$type . '_editor', $options ) ) {
312 $field_type = 'quill';
313 } elseif ( 'cleditor' === pods_v( static::$type . '_editor', $options ) ) {
314 $field_type = 'quill';
315 } else {
316 // Support custom WYSIWYG integration
317 $editor_type = pods_v( static::$type . '_editor', $options );
318 do_action( "pods_form_ui_field_wysiwyg_{$editor_type}", $name, $value, $options, $pod, $id );
319 do_action( 'pods_form_ui_field_wysiwyg', pods_v( static::$type . '_editor', $options ), $name, $value, $options, $pod, $id );
320
321 return;
322 }//end if
323
324 if ( ! empty( $options['disable_dfv'] ) ) {
325 return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
326 }
327
328 $type = pods_v( 'type', $options, static::$type );
329
330 $args = compact( array_keys( get_defined_vars() ) );
331 $args = (object) $args;
332
333 $this->render_input_script( $args );
334 }
335
336 /**
337 * {@inheritdoc}
338 */
339 public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
340 $value = $this->strip_html( $value, $options );
341 $value = $this->strip_shortcodes( $value, $options );
342 $value = $this->trim_whitespace( $value, $options );
343
344 $length = (int) pods_v( static::$type . '_max_length', $options, 0 );
345
346 if ( 0 < $length && $length < pods_mb_strlen( $value ) ) {
347 $value = pods_mb_substr( $value, 0, $length );
348 }
349
350 return $value;
351 }
352
353 /**
354 * {@inheritdoc}
355 */
356 public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
357 $value = $this->strip_html( $value, $options );
358 $value = $this->strip_shortcodes( $value, $options );
359 $value = $this->trim_whitespace( $value, $options );
360
361 $value = wp_trim_words( $value );
362
363 return $value;
364 }
365
366 /**
367 * {@inheritdoc}
368 */
369 public function strip_html( $value, $options = null ) {
370
371 $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
372
373 // Allow HTML tags on this field type, but it relies on the wysiwyg_allowed_html_tags option in the parent method.
374 $options[ static::$type . '_allow_html' ] = 1;
375
376 // If not set, use the default.
377 if ( ! isset( $options[ static::$type . '_sanitize_html' ] ) ) {
378 $options[ static::$type . '_sanitize_html' ] = 1;
379 }
380
381 return parent::strip_html( $value, $options );
382 }
383 }
384