PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.3
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 341 releases
← All changes | features/content-restriction/content-restriction-filtering.php +238 -2 3.16.3 → 4.0.3 View file →
@@ -240,8 +240,242 @@
240 240 }
241 241 add_filter( 'wppb_content_restriction_message_logged_in', 'wppb_content_restriction_message_wpautop', 30, 1 );
242 242 add_filter( 'wppb_content_restriction_message_logged_out', 'wppb_content_restriction_message_wpautop', 30, 1 );
243 243
244 +function wppb_content_restriction_get_post_preview_allowed_html() {
245 + $allowed_post_html = wp_kses_allowed_html( 'post' );
246 + $allowed_tags = array(
247 + 'a',
248 + 'abbr',
249 + 'acronym',
250 + 'b',
251 + 'blockquote',
252 + 'br',
253 + 'cite',
254 + 'code',
255 + 'dd',
256 + 'del',
257 + 'details',
258 + 'div',
259 + 'dl',
260 + 'dt',
261 + 'em',
262 + 'h1',
263 + 'h2',
264 + 'h3',
265 + 'h4',
266 + 'h5',
267 + 'h6',
268 + 'hr',
269 + 'i',
270 + 'ins',
271 + 'kbd',
272 + 'li',
273 + 'mark',
274 + 'ol',
275 + 'p',
276 + 'pre',
277 + 'q',
278 + 's',
279 + 'samp',
280 + 'small',
281 + 'span',
282 + 'strike',
283 + 'strong',
284 + 'sub',
285 + 'summary',
286 + 'sup',
287 + 'table',
288 + 'tbody',
289 + 'td',
290 + 'tfoot',
291 + 'th',
292 + 'thead',
293 + 'tr',
294 + 'u',
295 + 'ul',
296 + 'var',
297 + );
298 + $allowed_html = array();
299 +
300 + foreach( $allowed_tags as $tag ) {
301 + if( isset( $allowed_post_html[ $tag ] ) ) {
302 + $allowed_html[ $tag ] = $allowed_post_html[ $tag ];
303 + }
304 + }
305 +
306 + return apply_filters( 'wppb_content_restriction_post_preview_allowed_html', $allowed_html );
307 +}
308 +
309 +function wppb_content_restriction_sanitize_post_preview_html( $html ) {
310 + $html = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $html );
311 +
312 + return wp_kses( $html, wppb_content_restriction_get_post_preview_allowed_html() );
313 +}
314 +
315 +function wppb_content_restriction_get_text_count_units( $text, $offsets = false ) {
316 + if( str_starts_with( wp_get_word_count_type(), 'characters' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
317 + $pattern = ( wp_get_word_count_type() === 'characters_excluding_spaces' ) ? '/[^\n\r\t ]/u' : '/./u';
318 + } else {
319 + $pattern = '/[^\n\r\t ]+/u';
320 + }
321 +
322 + preg_match_all( $pattern, $text, $units, ( $offsets ? PREG_OFFSET_CAPTURE : 0 ) );
323 +
324 + return $units[0];
325 +}
326 +
327 +function wppb_content_restriction_count_dom_node_words( $node ) {
328 + $count = 0;
329 +
330 + if( ! $node->hasChildNodes() ) {
331 + return $count;
332 + }
333 +
334 + foreach( $node->childNodes as $child ) {
335 + if( $child->nodeType === XML_TEXT_NODE || $child->nodeType === XML_CDATA_SECTION_NODE ) {
336 + $count += count( wppb_content_restriction_get_text_count_units( $child->nodeValue ) );
337 + } else {
338 + $count += wppb_content_restriction_count_dom_node_words( $child );
339 + }
340 + }
341 +
342 + return $count;
343 +}
344 +
345 +function wppb_content_restriction_trim_text_node_words( $text, &$remaining_words, $more, &$trimmed, &$last_text_node ) {
346 + $words = wppb_content_restriction_get_text_count_units( $text, true );
347 +
348 + if( empty( $words ) ) {
349 + return $text;
350 + }
351 +
352 + if( $remaining_words <= 0 ) {
353 + if( ! empty( $last_text_node ) ) {
354 + $last_text_node->nodeValue = rtrim( $last_text_node->nodeValue ) . $more;
355 + }
356 +
357 + $trimmed = true;
358 +
359 + return '';
360 + }
361 +
362 + $word_count = count( $words );
363 +
364 + if( $word_count < $remaining_words ) {
365 + $remaining_words -= $word_count;
366 +
367 + return $text;
368 + }
369 +
370 + $last_text_node = null;
371 +
372 + if( $word_count === $remaining_words ) {
373 + $remaining_words = 0;
374 +
375 + return $text;
376 + }
377 +
378 + $last_word = $words[ $remaining_words - 1 ];
379 + $cut_position = $last_word[1] + strlen( $last_word[0] );
380 + $remaining_words = 0;
381 + $trimmed = true;
382 +
383 + return rtrim( substr( $text, 0, $cut_position ) ) . $more;
384 +}
385 +
386 +function wppb_content_restriction_trim_dom_node_words( $node, &$remaining_words, $more, &$trimmed, &$last_text_node ) {
387 + if( ! $node->hasChildNodes() ) {
388 + return;
389 + }
390 +
391 + $children = array();
392 + foreach( $node->childNodes as $child ) {
393 + $children[] = $child;
394 + }
395 +
396 + foreach( $children as $child ) {
397 + if( $trimmed ) {
398 + $node->removeChild( $child );
399 + continue;
400 + }
401 +
402 + if( $child->nodeType === XML_TEXT_NODE || $child->nodeType === XML_CDATA_SECTION_NODE ) {
403 + $child->nodeValue = wppb_content_restriction_trim_text_node_words( $child->nodeValue, $remaining_words, $more, $trimmed, $last_text_node );
404 +
405 + if( ! $trimmed && ! empty( wppb_content_restriction_get_text_count_units( $child->nodeValue ) ) ) {
406 + $last_text_node = $child;
407 + }
408 +
409 + if( $trimmed && $child->nodeValue === '' ) {
410 + $node->removeChild( $child );
411 + }
412 + } else {
413 + wppb_content_restriction_trim_dom_node_words( $child, $remaining_words, $more, $trimmed, $last_text_node );
414 +
415 + if( $trimmed && ! $child->hasChildNodes() ) {
416 + $node->removeChild( $child );
417 + }
418 + }
419 + }
420 +}
421 +
422 +function wppb_content_restriction_trim_html_words( $html, $num_words, $more = null ) {
423 + if( $more === null ) {
424 + $more = __( '&hellip;', 'profile-builder' );
425 + }
426 +
427 + $num_words = (int) $num_words;
428 +
429 + if( $num_words <= 0 || $html === '' ) {
430 + return '';
431 + }
432 +
433 + $html = wppb_content_restriction_sanitize_post_preview_html( $html );
434 +
435 + if( ! class_exists( 'DOMDocument' ) ) {
436 + return wpautop( wp_trim_words( $html, $num_words, $more ) );
437 + }
438 +
439 + $dom_flags = 0;
440 + if( defined( 'LIBXML_HTML_NOIMPLIED' ) ) {
441 + $dom_flags |= LIBXML_HTML_NOIMPLIED;
442 + }
443 + if( defined( 'LIBXML_HTML_NODEFDTD' ) ) {
444 + $dom_flags |= LIBXML_HTML_NODEFDTD;
445 + }
446 +
447 + $document = new DOMDocument();
448 + $previous_errors = libxml_use_internal_errors( true );
449 + $document->loadHTML( '<?xml encoding="UTF-8"><div id="wppb-content-restriction-preview-wrapper">' . $html . '</div>', $dom_flags );
450 + libxml_clear_errors();
451 + libxml_use_internal_errors( $previous_errors );
452 +
453 + $wrapper = $document->getElementById( 'wppb-content-restriction-preview-wrapper' );
454 +
455 + if( empty( $wrapper ) ) {
456 + return wpautop( wp_trim_words( $html, $num_words, $more ) );
457 + }
458 +
459 + $remaining_words = $num_words;
460 + $trimmed = false;
461 + $last_text_node = null;
462 + $more_text = html_entity_decode( $more, ENT_QUOTES | ENT_HTML5, get_option( 'blog_charset' ) );
463 +
464 + if( wppb_content_restriction_count_dom_node_words( $wrapper ) <= $num_words ) {
465 + return $html;
466 + }
467 +
468 + wppb_content_restriction_trim_dom_node_words( $wrapper, $remaining_words, $more_text, $trimmed, $last_text_node );
469 +
470 + $preview = '';
471 + foreach( $wrapper->childNodes as $child ) {
472 + $preview .= $document->saveHTML( $child );
473 + }
474 +
475 + return $preview;
476 +}
477 +
244 478 /* Adds a preview of the restricted post before the default restriction messages */
245 479 function wppb_content_restriction_add_post_preview( $message, $content, $post, $user_ID ) {
246 480
247 481 $preview = '';
@@ -261,11 +495,13 @@
261 495 if( $length !== 0 ) {
262 496 // Do shortcodes on the content
263 497 $post_content = do_shortcode( $post_content );
264 498
265 - // Trim the preview
266 - $preview = wp_trim_words( $post_content, $length, apply_filters( 'wppb_content_restriction_post_preview_more', __( '&hellip;', 'profile-builder' ) ) );
499 + // Trim the preview while preserving the post's HTML structure.
500 + $preview = wppb_content_restriction_trim_html_words( $post_content, $length, apply_filters( 'wppb_content_restriction_post_preview_more', __( '&hellip;', 'profile-builder' ) ) );
267 501 }
502 +
503 + return $preview . $message;
268 504 }
269 505
270 506 // More tag
271 507 if( $preview_option == 'more-tag' ) {