// Exit if accessed directly if ( ! defined( 'ABSPATH' ) ) exit; /** * Get the current post's TOC list or supplied post's TOC list. * * @access public * @since 2.0 * * @param int|null|WP_Post $post An instance of WP_Post or post ID. Defaults to current post. * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings. * * @return string */ function eztoc_get_toc_list( $post = null, $apply_content_filter = true ) { if ( ! $post instanceof WP_Post ) { $post = get_post( $post ); } if ( $apply_content_filter ) { $ezPost = new ezTOC_Post( $post ); } else { $ezPost = new ezTOC_Post( $post, false ); } return $ezPost->getTOCList(); } /** * Display the current post's TOC list or supplied post's TOC list. * * @access public * @since 2.0 * * @param null|WP_Post $post An instance of WP_Post * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings. */ function eztoc_list( $post = null, $apply_content_filter = true ) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason : Already escaped echo eztoc_get_toc_list( $post, $apply_content_filter ); } /** * Get the current post's TOC content block or supplied post's TOC content block. * * @access public * @since 2.0 * * @param int|null|WP_Post $post An instance of WP_Post or post ID. Defaults to current post. * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings. * * @return string */ function eztoc_get_toc_block( $post = null, $apply_content_filter = true ) { if ( ! $post instanceof WP_Post ) { $post = get_post( $post ); } if ( $apply_content_filter ) { $ezPost = new ezTOC_Post( $post ); } else { $ezPost = new ezTOC_Post( $post, false ); } return $ezPost->getTOC(); } /** * Display the current post's TOC content or supplied post's TOC content. * * @access public * @since 2.0 * * @param null|WP_Post $post An instance of WP_Post * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings. */ function eztoc_block( $post = null, $apply_content_filter = true ) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason : Already escaped echo eztoc_get_toc_block( $post, $apply_content_filter ); } // Non amp checker if ( ! function_exists('eztoc_is_amp_activated') ){ function eztoc_is_amp_activated() { $result = false; if (is_plugin_active('accelerated-mobile-pages/accelerated-moblie-pages.php') || is_plugin_active('amp/amp.php') || is_plugin_active('better-amp/better-amp.php') || is_plugin_active('wp-amp/wp-amp.php') || is_plugin_active('amp-wp/amp-wp.php') || is_plugin_active('bunyad-amp/bunyad-amp.php') ) $result = true; return $result; } } // Non amp checker if ( ! function_exists('eztoc_non_amp') ) { function eztoc_non_amp() { $non_amp = true; if( function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint() ) { $non_amp = false; } if( function_exists('is_amp_endpoint') && is_amp_endpoint() ){ $non_amp = false; } if( function_exists('is_better_amp') && is_better_amp() ){ $non_amp = false; } if( function_exists('is_amp_wp') && is_amp_wp() ){ $non_amp = false; } return $non_amp; } } /** * MBString Extension Admin Notice * if not loaded then msg to user * @since 2.0.47 */ if ( function_exists('extension_loaded') && extension_loaded('mbstring') == false ) { function eztoc_admin_notice_for_mbstring_extension() { echo '

' . esc_html__( 'PHP MBString Extension is not enabled in your php setup, please enabled to work perfectly', 'easy-table-of-contents' ) . ' ' . esc_html__( 'Easy Table of Contents', 'easy-table-of-contents' ) . '. ' . esc_html__( 'Check official doc:', 'easy-table-of-contents' ). ' ' . esc_html__( 'PHP Manual', 'easy-table-of-contents' ) .'

'; } add_action('admin_notices', 'eztoc_admin_notice_for_mbstring_extension'); } /** * Since version 2.0.52 * Export all settings to json file */ add_action( 'wp_ajax_eztoc_export_all_settings', 'eztoc_export_all_settings'); function eztoc_export_all_settings() { if ( !current_user_can( 'manage_options' ) ) { die('-1'); } if(!isset($_GET['_wpnonce'])){ die('-1'); } if( !wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ) , '_wpnonce' ) ){ //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized --Nonce is validated die('-1'); } $export_settings_data = get_option('ez-toc-settings'); if(empty($export_settings_data)){ $export_settings_data = array(); } header('Content-type: application/json'); header('Content-disposition: attachment; filename=ez_toc_settings_backup.json'); echo wp_json_encode($export_settings_data); wp_die(); } /** * Adding page/post title in TOC list * @since 2.0.56 */ add_action( 'init', function() { if(ezTOC_Option::get('show_title_in_toc') == 1 && !is_admin()) { ob_start(); } } ); add_action('shutdown', function() { if(ezTOC_Option::get('show_title_in_toc') == 1 && !is_admin()){ $final = ''; $levels = ob_get_level(); for ($i = 0; $i < $levels; $i++) { $final .= ob_get_clean(); } //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason : This if final output buffer echo apply_filters('eztoc_wordpress_final_output', $final); } }, 10); add_filter('eztoc_wordpress_final_output', function($content){ if(!is_singular('post') && !is_page()) { return $content;} if(ezTOC_Option::get('show_title_in_toc') == 1 && !is_admin()){ return preg_replace_callback( '/(.*?)<\/body>/is', function ($matches) { $body_content = $matches[1]; return preg_replace_callback( '/(.*?)<\/h1>/i', function ($h1_matches) { $title = $h1_matches[2]; $added_link = ''; $added_link .= esc_attr($title); $added_link .= ''; return $added_link; }, $body_content ); }, $content ); } }, 10, 1); add_filter( 'ez_toc_modify_process_page_content', 'eztoc_page_content_include_page_title', 10, 1 ); function eztoc_page_content_include_page_title( $content ) { if(ezTOC_Option::get('show_title_in_toc') == 1 && !is_admin()){ $title = get_the_title(); $added_page_title= '

'.wp_kses_post($title).'

'; $content = $added_page_title.$content; } return $content; } function ezTOCGenerateHeadingIDFromTitle( $heading ) { $return = false; if ( $heading ) { //This is legacy filter, will be removed in future updates. $heading = apply_filters( 'ez_toc_url_anchor_target_before', $heading ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound //This is new filter, please use this for future compatibility $heading = apply_filters( 'eztoc_url_anchor_target_before', $heading ); $return = html_entity_decode( $heading, ENT_QUOTES, get_option( 'blog_charset' ) ); $return = trim( wp_strip_all_tags( $return ) ); $return = remove_accents( $return ); $return = str_replace( array( "\r", "\n", "\n\r", "\r\n" ), ' ', $return ); $return = htmlentities2( $return ); $return = str_replace( array( '&', ' '), ' ', $return ); $return = str_replace( array( '­' ),'', $return ); // removed silent hypen $return = html_entity_decode( $return, ENT_QUOTES, get_option( 'blog_charset' ) ); $return = preg_replace( '/[\x00-\x1F\x7F]*/u', '', $return ); $return = str_replace( array( '*', '\'', '(', ')', ';', '@', '&', '=', '+', '$', ',', '/', '?', '#', '[', ']' ), '', $return ); $return = str_replace( array( '%', '{', '}', '|', '\\', '^', '~', '[', ']', '`' ), '', $return ); $return = str_replace( array( '$', '.', '+', '!', '*', '\'', '(', ')', ',', '’' ), '', $return ); $return = str_replace( array( '-', '-', '–', '—' ), '-', $return ); $return = str_replace( array( '‘', '’', '“', '”' ), '', $return ); $return = str_replace( array( ':' ), '_', $return ); $return = preg_replace( '/\s+/', '_', $return ); $return = preg_replace( '/-+/', '-', $return ); $return = preg_replace( '/_+/', '_', $return ); $return = rtrim( $return, '-_' ); $return = preg_replace_callback( "{[^0-9a-z_.!~*'();,/?:@&=+$#-]}i", function( $m ) { return sprintf( '%%%02X', ord( $m[0] ) ); }, $return ); if ( ezTOC_Option::get( 'lowercase' ) ) { $return = strtolower( $return ); } if ( !$return || true == ezTOC_Option::get( 'all_fragment_prefix' ) ) { $return = ( ezTOC_Option::get( 'fragment_prefix' ) ) ? ezTOC_Option::get( 'fragment_prefix' ) : '_'; } if ( ezTOC_Option::get( 'hyphenate' ) ) { $return = str_replace( '_', '-', $return ); $return = preg_replace( '/-+/', '-', $return ); } } //This is legacy filter, will be removed in future updates. $return = apply_filters( 'ez_toc_url_anchor_target', $return, $heading ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound //This is new filter, please use this for future compatibility $return = apply_filters( 'eztoc_url_anchor_target', $return, $heading ); return $return; } //Device Eligibility //@since 2.0.60 function eztoc_auto_device_target_status(){ global $post; if ( ! ( $post instanceof WP_Post ) || empty( $post->ID ) ) { return true; } $status = true; $global_target = ezTOC_Option::get( 'device_target' ); $post_target = get_post_meta( $post->ID, '_ez-toc-device-target', true ); $target = $post_target ? $post_target : $global_target; if($target == 'mobile'){ if(function_exists('wp_is_mobile') && wp_is_mobile()){ $status = true; }else{ $status = false; } } if($target == 'desktop'){ if(function_exists('wp_is_mobile') && wp_is_mobile()){ $status = false; }else{ $status = true; } } return $status; } /** * Get normalized sticky TOC device target option. * * @since 2.0.80 * * @return string */ function eztoc_get_sticky_device_target() { $target = ezTOC_Option::get( 'sticky_device_target', '' ); if ( 'Select' === $target ) { $target = ''; } // Backward compatibility: desktop + legacy tablet checkbox. if ( 'desktop' === $target && ezTOC_Option::get( 'sticky_enable_on_tablet' ) ) { $target = 'desktop_tablet'; } $allowed = array( '', 'desktop', 'tablet', 'mobile', 'desktop_tablet', 'desktop_mobile', 'tablet_mobile', ); if ( ! in_array( $target, $allowed, true ) ) { return ''; } return $target; } /** * Check whether sticky TOC device targeting uses client-side viewport detection. * * @since 2.0.80 * * @param string $target Optional normalized device target. * * @return bool */ function eztoc_sticky_device_target_uses_client_detection( $target = null ) { if ( null === $target ) { $target = eztoc_get_sticky_device_target(); } return ! empty( $target ); } /** * Check for the enable support of sticky toc/toggle * @since 2.0.60 */ function eztoc_stikcy_enable_support_status() { $status = false; if ( ezTOC_Option::get('sticky-toggle') ) { //This is legacy filter, will be removed in future updates. $sticky_post_types = apply_filters( 'ez_toc_sticky_post_types', ezTOC_Option::get( 'sticky-post-types' ) ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound //This is new filter, please use this for future compatibility $sticky_post_types = apply_filters( 'eztoc_sticky_post_types', ezTOC_Option::get( 'sticky-post-types' ) ); if ( ! empty( $sticky_post_types ) ){ if ( is_singular() && !is_front_page() ) { $postType = get_post_type(); if ( in_array($postType,$sticky_post_types) ) { $status = true; } } } if ( ezTOC_Option::get( 'sticky_include_homepage' ) ) { if ( is_front_page() || is_home() ) { $status = true; } } if ( ezTOC_Option::get( 'sticky_include_category' ) ) { if ( is_category() ) { $status = true; } } if ( ezTOC_Option::get( 'sticky_include_tag' ) ) { if ( is_tag() ) { $status = true; } } if ( ezTOC_Option::get( 'sticky_include_product_category' ) ) { if ( is_tax( 'product_cat' ) ) { $status = true; } } if ( ezTOC_Option::get( 'sticky_include_custom_tax' ) ) { if ( is_tax() ) { $status = true; } } if ( ezTOC_Option::get( 'sticky_restrict_url_text' ) && ezTOC_Option::get( 'sticky_restrict_url_text' ) != '' ){ $all_urls = nl2br( ezTOC_Option::get( 'sticky_restrict_url_text' ) ); $all_urls = str_replace( '
', '', $all_urls ); $urls_arr = explode( PHP_EOL, $all_urls ); if ( is_array($urls_arr) ) { $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; foreach ( $urls_arr as $url_arr ) { if ( $request_uri && false !== strpos( $request_uri, trim( $url_arr ) ) ) { $status = false; break; } } } } } //This is legacy filter, will be removed in future updates. $eztoc_sticky_enable_support = apply_filters( 'ez_toc_sticky_enable_support', $status ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound //This is new filter, please use this for future compatibility $eztoc_sticky_enable_support = apply_filters( 'eztoc_sticky_enable_support', $eztoc_sticky_enable_support ); return $eztoc_sticky_enable_support; } /** * Helps exclude blockquote * @since 2.0.58 */ if(!function_exists('eztoc_para_blockquote_replace')){ function eztoc_para_blockquote_replace($blockquotes, $content, $step){ $bId = 0; if($step == 1){ foreach($blockquotes[0] as $blockquote){ $replace = '#eztocbq' . $bId . '#'; $content = str_replace( trim($blockquote), $replace, $content ); $bId++; } }elseif($step == 2){ foreach($blockquotes[0] as $blockquote){ $search = '#eztocbq' . $bId . '#'; $content = str_replace( $search, trim($blockquote), $content ); $bId++; } } return $content; } } /** * Check the status of shortcode enable support which is defined in shortcode attributes * @since 2.0.59 */ function eztoc_shortcode_enable_support_status($atts){ $status = true; if(isset($atts['post_types'])){ $exp_post_types = explode(',', $atts['post_types']); if(!empty($exp_post_types)){ $exp_post_types = array_map("trim",$exp_post_types); if(is_singular()){ $curr_post_type = get_post_type(); if(in_array($curr_post_type, $exp_post_types )){ $status = true; }else{ $status = false; } }else{ $status = false; } } } if(isset($atts['post_in'])){ $exp_post_ids = explode(',', $atts['post_in']); if(!empty($exp_post_ids)){ $exp_post_ids = array_map("trim",$exp_post_ids); if(is_singular()){ $ID = get_the_ID(); if(in_array($ID, $exp_post_ids )){ $status = true; }else{ $status = false; } }else{ $status = false; } } } if(isset($atts['post_not_in'])){ $exp_post_ids = explode(',', $atts['post_not_in']); if(!empty($exp_post_ids)){ $exp_post_ids = array_map("trim",$exp_post_ids); if(is_singular()){ $ID = get_the_ID(); if(!in_array($ID, $exp_post_ids )){ $status = true; }else{ $status = false; } }else{ $status = false; } } } if(isset($atts['device_target']) && $atts['device_target'] != ''){ $status = false; $my_device = $atts['device_target']; if(function_exists('wp_is_mobile') && wp_is_mobile()){ if($my_device == 'mobile'){ $status = true; } }else{ if($my_device == 'desktop'){ $status = true; } } } return $status; } /** * Display No heading found text when there are no heading present in the content * @since 2.0.66 */ add_filter('eztoc_shortcode_final_toc_html','eztoc_shortcode_html_no_heading_text'); add_filter('eztoc_autoinsert_final_toc_html','eztoc_shortcode_html_no_heading_text'); function eztoc_shortcode_html_no_heading_text($html){ if(empty($html)){ if( ezTOC_Option::get( 'no_heading_text' ) == 1 && ezTOC_Option::get( 'no_heading_text_value' )){ $no_heading_text_value = !empty(ezTOC_Option::get( 'no_heading_text_value' ))?esc_html(ezTOC_Option::get( 'no_heading_text_value' )):'No heading found'; $html = '
' . $no_heading_text_value . '
'; } } return $html; } /** * Added [no-ez-toc] to disbale TOC on specific page/post * @since 2.0.56 */ add_shortcode( 'no-ez-toc', 'eztoc_noeztoc_callback' ); function eztoc_noeztoc_callback( $atts, $content = "" ) { add_filter( 'ez_toc_maybe_apply_the_content_filter', function( $apply ) { return false; } ,999 ); // condition when `the_content` filter is not used by the theme add_filter( 'ez_toc_modify_process_page_content', function( $apply ) { return ''; } ,999 ); return $content; } /** * Added [no-toc] to support migrated shortcode from TOC+ * @since 2.0.70 */ add_shortcode( 'no-toc', 'eztoc_notoc_callback' ); function eztoc_notoc_callback( $atts, $content = "" ) { add_filter( 'ez_toc_maybe_apply_the_content_filter', function( $apply ) { return false; } ,999 ); // condition when `the_content` filter is not used by the theme add_filter( 'ez_toc_modify_process_page_content', function( $apply ) { return ''; } ,999 ); return $content; } add_action( 'admin_init' , 'eztoc_redirect' ); function eztoc_redirect( ) { if ( get_option( 'ez_toc_do_activation_redirect' , false ) ) { delete_option( 'ez_toc_do_activation_redirect' ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: Nonce not required here if( !isset( $_GET['activate-multi'] ) ) { wp_safe_redirect( "options-general.php?page=table-of-contents#welcome" ); } } } /** * eztoc_wp_strip_all_tags method inspired by WordPress actual wp_strip_all_tags * to strip all tags from the given text * Access Public * @since 2.0.70 * @param $text, $remove_breaks * @return string */ function eztoc_wp_strip_all_tags( $text, $remove_breaks = false ) { if ( is_null( $text ) ) { return ''; } if ( ! is_scalar( $text ) ) { /* * To maintain consistency with pre-PHP 8 error levels, * trigger an E_USER_WARNING rather than _doing_it_wrong(), * which triggers an E_USER_NOTICE. * Use trigger_error() for WP < 6.4 compatibility (min supported: 5.0). */ $message = sprintf( /* translators: 1: The function name, 2: The argument number, 3: The argument name, 4: The expected type, 5: The provided type. */ __( 'Warning: %1$s expects parameter %2$s (%3$s) to be a %4$s, %5$s given.', 'easy-table-of-contents' ), __FUNCTION__, '#1', '$text', 'string', gettype( $text ) ); if ( function_exists( 'wp_trigger_error' ) ) { wp_trigger_error( '', $message, E_USER_WARNING ); } else { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error trigger_error( esc_html( $message ), E_USER_WARNING ); } return ''; } $text = preg_replace( '@<(script|style)[^>]*?>.*?@si', '', $text ); //This is legacy hook, will be removed in future updates. $text = wp_strip_all_tags( $text, apply_filters( 'ez_toc_allowable_tags', '' ) ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound //This is new hook, please use this for future compatibility $text = wp_strip_all_tags( $text, apply_filters( 'eztoc_allowable_tags', '' ) ); if ( $remove_breaks ) { $text = preg_replace( '/[\r\n\t ]+/', ' ', $text ); } return trim( $text ); } /** * Helps allow line breaks * @since 2.0.59 */ add_filter( 'ez_toc_allowable_tags', 'eztoc_link_allow_br_tag' ); function eztoc_link_allow_br_tag( $tags ) { if ( ezTOC_Option::get( 'prsrv_line_brk' ) ) { $tags = '
'; } return $tags; } /** * Truncate headings as per settings * @since 2.0.71 * @param $heading * @return string */ add_filter( 'ez_toc_title', function( $heading ) { $truncate_headings = ezTOC_Option::get( 'truncate_headings' ); $truncate_headings_words = ezTOC_Option::get( 'truncate_headings_words' ); $truncate_headings_special = ezTOC_Option::get( 'truncate_headings_special' ); if ( $truncate_headings ) { if ( $truncate_headings == 'words' && $truncate_headings_words ) { $heading = wp_trim_words( $heading, intval($truncate_headings_words)); }else if ( $truncate_headings == 'special' && $truncate_headings_special ) { if ( strpos( $heading, $truncate_headings_special ) !== false ) { $parts = explode( $truncate_headings_special, $heading, 2 ); if ( isset( $parts[0] ) && strlen( $parts[0] ) > 0 ) { $heading = trim( $parts[0] ); } } } } return $heading; } ); https://urban-earth.co.uk/post-sitemap.xml 2025-05-29T07:48:46+00:00 https://urban-earth.co.uk/page-sitemap.xml 2026-06-18T10:25:51+00:00 https://urban-earth.co.uk/projects-sitemap.xml 2026-06-18T10:32:34+00:00 https://urban-earth.co.uk/building_projects-sitemap.xml 2023-01-23T12:19:51+00:00 https://urban-earth.co.uk/news-sitemap.xml 2022-03-03T11:32:03+00:00 https://urban-earth.co.uk/projects-wales-sitemap.xml 2024-09-04T08:44:07+00:00