Plugin Directory

Changeset 3492911


Ignore:
Timestamp:
03/27/2026 06:34:46 PM (17 hours ago)
Author:
apos37
Message:

1.3.7.4

  • Fix: Added support for Elementor when replacing links from results page (props @nazrinn)
  • Update: Added good links and status on console results
Location:
broken-link-notifier
Files:
56 added
8 edited

Legend:

Unmodified
Added
Removed
  • broken-link-notifier/trunk/broken-link-notifier.php

    r3486590 r3492911  
    44 * Plugin URI:          https://pluginrx.com/plugin/broken-link-notifier/
    55 * Description:         Get notified when someone loads a page with a broken link
    6  * Version:             1.3.7.3
     6 * Version:             1.3.7.4
    77 * Requires at least:   5.9
    88 * Tested up to:        6.9
     
    7171define( 'BLNOTIFIER_PLUGIN_DIR', plugins_url( '/'.BLNOTIFIER_TEXTDOMAIN.'/' ) );                                //: https://domain.com/wp-content/plugins/broken-link-notifier/
    7272define( 'BLNOTIFIER_PLUGIN_INCLUDES_PATH', plugin_dir_path( __FILE__ ).'includes/' );                           //: /home/.../public_html/wp-content/plugins/broken-link-notifier/includes/
     73define( 'BLNOTIFIER_PLUGIN_JS_ABSPATH', BLNOTIFIER_PLUGIN_INCLUDES_PATH . 'js/' );                              //: /home/.../public_html/wp-content/plugins/broken-link-notifier/includes/js/
    7374define( 'BLNOTIFIER_PLUGIN_JS_PATH', str_replace( site_url(), '', BLNOTIFIER_PLUGIN_DIR ).'includes/js/' );     //: /wp-content/plugins/broken-link-notifier/includes/js/
    7475define( 'BLNOTIFIER_PLUGIN_CSS_PATH', str_replace( site_url(), '', BLNOTIFIER_PLUGIN_DIR ).'includes/css/' );   //: /wp-content/plugins/broken-link-notifier/includes/css/
  • broken-link-notifier/trunk/includes/helpers.php

    r3481332 r3492911  
    8585     */
    8686    public function get_bad_status_codes() {
    87         $default_codes = [ 666, 308, 400, 404, 408 ];
     87        $default_codes = [ 0, 666, 308, 400, 404, 408 ];
    8888
    8989        $types = filter_var_array( get_option( 'blnotifier_status_codes', [] ), FILTER_SANITIZE_FULL_SPECIAL_CHARS );
  • broken-link-notifier/trunk/includes/js/results-back.js

    r3481394 r3492911  
    162162    function saveLink( inputField, oldLink, sourceID, linkID ) {
    163163        let newLink = inputField.val().trim();
     164        console.log( `Saving new link (${newLink})...`, { oldLink, sourceID, linkID } );
    164165   
    165166        // If the new link is empty, revert to the original
     
    191192                if ( response.success ) {
    192193                    console.log( 'Link updated successfully.' );
     194                    if ( response.data.details ) {
     195                        console.log( 'Details:', response.data.details );
     196                    }
    193197
    194198                    // Replace the old data-link in the Replace Link attribute
     
    197201                    // Replace the source blink
    198202                    let viewPageLink = $( `tr#link-${linkID} .source .row-actions .view a` );
    199                     let currentHref = viewPageLink.attr( 'href' );
    200                     let newBlinkUrl = encodeURIComponent( newLink );
    201                     let updatedHref = currentHref.replace( /(blink=)[^\&]*/, `$1${newBlinkUrl}` );
    202                     viewPageLink.attr( 'href', updatedHref );
     203                    if ( viewPageLink.length ) {
     204                        let currentHref = viewPageLink.attr( 'href' );
     205                        let newBlinkUrl = encodeURIComponent( newLink );
     206                        let updatedHref = currentHref.replace( /(blink=)[^\&]*/, `$1${newBlinkUrl}` );
     207                        viewPageLink.attr( 'href', updatedHref );
     208                    }
    203209
    204210                    // Update the type
    205211                    $( `#link-${linkID} .bln-type` ).addClass( 'fixed' ).text( 'Replaced' );
    206                     $( `#link-${linkID} .bln_type code` ).remove();
    207                     $( `#link-${linkID} .bln_type .message` ).html( `The old link has been replaced. Result will be removed.<br>Old link: ${oldLink}` );
     212                    $( `#link-${linkID} .type .code` ).remove();
     213                    $( `#link-${linkID} .type .message` ).html( `The old link has been replaced. Result will be removed after refresh.<br>Old link: ${oldLink}` );
    208214
    209215                    // Remove omit link action
     
    223229                   
    224230                } else {
    225                     alert( response.data );
     231                    // Alert the specific msg from the PHP side
     232                    let errorMsg = ( response.data && response.data.msg ) ? response.data.msg : 'Unknown error occurred.';
     233                    alert( 'Update Failed: ' + errorMsg );
     234                   
     235                    // Revert the link text in the UI since the DB didn't update
     236                    newLinkElement.replaceWith( `<a href="${oldLink}" class="link-url" target="_blank" rel="noopener">${oldLink}</a>` );
    226237                }
    227238            },
    228239            error: function() {
    229                 alert('Something went wrong. Please try again.');
     240                alert( 'Something went wrong with the server request. Please try again.' );
     241                // Revert the link text in the UI
     242                newLinkElement.replaceWith( `<a href="${oldLink}" class="link-url" target="_blank" rel="noopener">${oldLink}</a>` );
    230243            }
    231244        } );
  • broken-link-notifier/trunk/includes/js/results-front.js

    r3481394 r3492911  
    108108                        console.log( '%c Broken Link Scan Results: ', 'background: #2570AC; color: white' );
    109109                        if ( response.notify ) {
     110                            console.log( '%c Bad links found: ', 'background: #222; color: #bada55' );
    110111                            console.error( response.notify );
    111112                        } else {
    112                             console.info( 'No broken links found. :)' );
     113                            console.info( '%c No broken links found. :)', 'background: #222; color: #bada55' );
     114                        }
     115                        if ( response.msg ) {
     116                            console.log( `%c ${response.msg} `, 'background: #2570AC; color: white' );
     117                        }
     118                        if ( response.good_links ) {
     119                            console.log( '%c Good links found: ', 'background: #222; color: #bada55' );
     120                            console.log( response.good_links );
    113121                        }
    114122                        console.log( `%c ${response.timing} `, 'background: #2570AC; color: white' );
  • broken-link-notifier/trunk/includes/js/results-front.min.js

    r3481394 r3492911  
    1 jQuery(o=>{const n=blnotifier_front_end.elements,e=window.location.search,i=new URLSearchParams(e);if(i.has("blink")){console.log("Looking for highlights; checking for broken links paused.");const e=i.get("blink");o.each(n,function(n,i){o(n).not("#wpadminbar "+n).each(function(n){const t=o(this).attr(i);if(void 0!==t&&t.includes(e))if(o(this).addClass("glowText"),o(this).is(":hidden")){var r="It looks like one or more of the links are hidden. To find them, try searching for it in your browser's Developer console.";console.log(r),alert(r)}else console.log("The element should glow yellow if it is visible on the page. If you do not see it on the page, then it is hidden somewhere. Check any JavaScript elements, too. You can try searching for it in your browser's Developer console.")})})}else{blnotifier_front_end.show_in_console&&console.log("%c Fetching links using the Broken Link Notifier Plugin... ","background: #2570AC; color: white");var t=[],r=[],s=[];o.each(n,function(n,e){o(n).each(function(n){const i=o(this).attr(e),l=o(this).parents("#wpadminbar").length,c=o(this).parents("header").length,a=o(this).parents("footer").length;void 0===i||l||(blnotifier_front_end.scan_header&&c?t.push(i):blnotifier_front_end.scan_footer&&a?s.push(i):c||a||r.push(i))})}),blnotifier_front_end.show_in_console&&(blnotifier_front_end.scan_header&&(console.log("%c Header links found: ","background: #222; color: #bada55"),console.log(t)),console.log("%c Content links found: ","background: #222; color: #bada55"),console.log(r),blnotifier_front_end.scan_header&&(console.log("%c Footer links found: ","background: #222; color: #bada55"),console.log(s)),console.log("%c Scanning for broken links... please wait. This may take a few minutes if there are a lot of links.","background: #2570AC; color: white"));var l=blnotifier_front_end.nonce;o.ajax({type:"post",dataType:"json",url:blnotifier_front_end.ajaxurl,data:{action:"blnotifier_blinks",nonce:l,scan_header:blnotifier_front_end.scan_header,scan_footer:blnotifier_front_end.scan_footer,source_url:window.location.href,header_links:t,content_links:r,footer_links:s},success:function(e){if("success"==e.type)blnotifier_front_end.show_in_console&&(console.log("%c Broken Link Scan Results: ","background: #2570AC; color: white"),e.notify?console.error(e.notify):console.info("No broken links found. :)"),console.log(`%c ${e.timing} `,"background: #2570AC; color: white")),i.has("blinks")&&"true"==i.get("blinks")&&o.each(e.notify,function(e,i){o.each(i,function(e,i){o.each(n,function(n,e){o(n).each(function(n){var t=o(this).attr(e);i.link==t&&o(this).addClass("glowText")})})})});else if("error"==e.type){var t=e.msg?e.msg:"Unknown error occurred.";console.error("Scan failed: "+t)}}})}});
     1jQuery(o=>{const n=blnotifier_front_end.elements,e=window.location.search,i=new URLSearchParams(e);if(i.has("blink")){console.log("Looking for highlights; checking for broken links paused.");const e=i.get("blink");o.each(n,function(n,i){o(n).not("#wpadminbar "+n).each(function(n){const r=o(this).attr(i);if(void 0!==r&&r.includes(e))if(o(this).addClass("glowText"),o(this).is(":hidden")){var l="It looks like one or more of the links are hidden. To find them, try searching for it in your browser's Developer console.";console.log(l),alert(l)}else console.log("The element should glow yellow if it is visible on the page. If you do not see it on the page, then it is hidden somewhere. Check any JavaScript elements, too. You can try searching for it in your browser's Developer console.")})})}else{blnotifier_front_end.show_in_console&&console.log("%c Fetching links using the Broken Link Notifier Plugin... ","background: #2570AC; color: white");var r=[],l=[],s=[];o.each(n,function(n,e){o(n).each(function(n){const i=o(this).attr(e),t=o(this).parents("#wpadminbar").length,c=o(this).parents("header").length,a=o(this).parents("footer").length;void 0===i||t||(blnotifier_front_end.scan_header&&c?r.push(i):blnotifier_front_end.scan_footer&&a?s.push(i):c||a||l.push(i))})}),blnotifier_front_end.show_in_console&&(blnotifier_front_end.scan_header&&(console.log("%c Header links found: ","background: #222; color: #bada55"),console.log(r)),console.log("%c Content links found: ","background: #222; color: #bada55"),console.log(l),blnotifier_front_end.scan_header&&(console.log("%c Footer links found: ","background: #222; color: #bada55"),console.log(s)),console.log("%c Scanning for broken links... please wait. This may take a few minutes if there are a lot of links.","background: #2570AC; color: white"));var t=blnotifier_front_end.nonce;o.ajax({type:"post",dataType:"json",url:blnotifier_front_end.ajaxurl,data:{action:"blnotifier_blinks",nonce:t,scan_header:blnotifier_front_end.scan_header,scan_footer:blnotifier_front_end.scan_footer,source_url:window.location.href,header_links:r,content_links:l,footer_links:s},success:function(e){if("success"==e.type)blnotifier_front_end.show_in_console&&(console.log("%c Broken Link Scan Results: ","background: #2570AC; color: white"),e.notify?(console.log("%c Bad links found: ","background: #222; color: #bada55"),console.error(e.notify)):console.info("%c No broken links found. :)","background: #222; color: #bada55"),e.msg&&console.log(`%c ${e.msg} `,"background: #2570AC; color: white"),e.good_links&&(console.log("%c Good links found: ","background: #222; color: #bada55"),console.log(e.good_links)),console.log(`%c ${e.timing} `,"background: #2570AC; color: white")),i.has("blinks")&&"true"==i.get("blinks")&&o.each(e.notify,function(e,i){o.each(i,function(e,i){o.each(n,function(n,e){o(n).each(function(n){var r=o(this).attr(e);i.link==r&&o(this).addClass("glowText")})})})});else if("error"==e.type){var r=e.msg?e.msg:"Unknown error occurred.";console.error("Scan failed: "+r)}}})}});
  • broken-link-notifier/trunk/includes/page-results.php

    r3486590 r3492911  
    320320                        <input type="checkbox" id="cb-select-<?php echo esc_attr( $link->id ); ?>" class="bln-row-checkbox" name="bln_selected[]" value="<?php echo esc_attr( $link->id ); ?>" />
    321321                    </th>
    322                     <td class="type"><?php echo wp_kses_post( $type_label ); ?> <code<?php echo wp_kses_post( $incl_title ); ?>><?php echo esc_html__( 'Code:', 'broken-link-notifier' ); ?> <?php echo wp_kses_post( $code_link ); ?></code> <span class="message"><?php echo esc_html( $link->text ); ?></span></td>
     322                    <td class="type">
     323                        <?php echo wp_kses_post( $type_label ); ?> <code class="code"<?php echo wp_kses_post( $incl_title ); ?>><?php echo esc_html__( 'Code:', 'broken-link-notifier' ); ?> <?php echo wp_kses_post( $code_link ); ?></code> <span class="message"><?php echo esc_html( $link->text ); ?></span>
     324                    </td>
    323325                    <td class="link">
    324326                        <a href="<?php echo esc_url( $link->link ); ?>" class="link-url" target="_blank" rel="noopener"><?php echo esc_html( $link->link ); ?></a>
  • broken-link-notifier/trunk/includes/results.php

    r3486590 r3492911  
    730730            $result[ 'type' ] = 'success';
    731731            $result[ 'notify' ] = $notify;
     732            $result[ 'good_links' ] = $good_links;
    732733            $result[ 'timing' ] = 'Results were generated in '.$total_time.' seconds ('.$sec_per_link.'/link)';
    733734
     
    863864    public function ajax_replace_link() {
    864865        // Verify nonce
    865         if ( !isset( $_REQUEST[ 'nonce' ] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash ( $_REQUEST[ 'nonce' ] ) ), $this->nonce_replace ) ) {
    866             exit( 'No naughty business please.' );
    867         }
    868 
    869         $HELPERS = new BLNOTIFIER_HELPERS;
    870         if ( !$HELPERS->user_can_manage_broken_links() ) {
    871             exit( 'Unauthorized access.' );
    872         }
    873    
    874         // Get the vars
    875         $link_id    = isset( $_REQUEST[ 'linkID' ] ) ? absint( wp_unslash( $_REQUEST[ 'linkID' ] ) ) : false;
    876         $oldLink    = isset( $_REQUEST[ 'oldLink' ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ 'oldLink' ] ) ) : false;
    877         $newLink    = isset( $_REQUEST[ 'newLink' ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ 'newLink' ] ) ) : false;
    878         $source_id  = isset( $_REQUEST[ 'sourceID' ] ) ? absint( wp_unslash( $_REQUEST[ 'sourceID' ] ) ) : false;
    879 
    880         if ( $oldLink && $newLink && $source_id && get_post( $source_id ) ) {
    881 
    882             // Get the current post content
    883             $post_content = get_post_field( 'post_content', $source_id );
    884 
    885             // Replace old link with new link in the content
    886             $updated_content = str_replace( $oldLink, $newLink, $post_content );
    887 
    888             // Update the post content
    889             $updated_post = [
     866        if ( ! isset( $_REQUEST[ 'nonce' ] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST[ 'nonce' ] ) ), $this->nonce_replace ) ) {
     867            wp_send_json_error( [ 'msg' => 'No naughty business please.' ] );
     868        }
     869
     870        $HELPERS = new BLNOTIFIER_HELPERS();
     871        if ( ! $HELPERS->user_can_manage_broken_links() ) {
     872            wp_send_json_error( [ 'msg' => 'Unauthorized access.' ] );
     873        }
     874
     875        $link_id   = isset( $_REQUEST[ 'linkID' ] ) ? absint( wp_unslash( $_REQUEST[ 'linkID' ] ) ) : false;
     876        $old_link  = isset( $_REQUEST[ 'oldLink' ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ 'oldLink' ] ) ) : false;
     877        $new_link  = isset( $_REQUEST[ 'newLink' ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ 'newLink' ] ) ) : false;
     878        $source_id = isset( $_REQUEST[ 'sourceID' ] ) ? absint( wp_unslash( $_REQUEST[ 'sourceID' ] ) ) : false;
     879
     880        if ( ! $old_link || ! $new_link || ! $source_id ) {
     881            wp_send_json_error( [ 'msg' => 'Missing required parameters.' ] );
     882        }
     883
     884        $post = get_post( $source_id );
     885        if ( ! $post ) {
     886            wp_send_json_error( [ 'msg' => 'Source post not found.' ] );
     887        }
     888
     889        $updated = false;
     890        $fail_reason = 'Link not found in post content or metadata.';
     891        $details = [];
     892
     893        // 1. Standard WordPress Content
     894        $post_content = $post->post_content;
     895        if ( strpos( $post_content, $old_link ) !== false ) {
     896            $details[] = 'Found in standard WordPress post content.';
     897            $new_content = str_replace( $old_link, $new_link, $post_content );
     898            $result      = wp_update_post( [
    890899                'ID'           => $source_id,
    891                 'post_content' => $updated_content,
    892             ];
    893 
    894             // Update the post in the database
    895             $result = wp_update_post( $updated_post );
    896             if ( !is_wp_error( $result ) ) {
    897 
    898                 // Let's also delete the result
    899                 $this->remove( $HELPERS->str_replace_on_link( $oldLink ), $link_id );
    900 
    901                 // Respond
    902                 wp_send_json_success();
     900                'post_content' => $new_content,
     901            ] );
     902
     903            if ( is_wp_error( $result ) ) {
     904                $fail_reason = 'WP_Error: ' . $result->get_error_message();
     905                $details[] = 'Failed to update standard post content.';
    903906            } else {
    904                 wp_send_json_error( 'Failed to update the post: ' . $result->get_error_message() );
    905             }
    906         }
    907 
    908         // Failure
    909         wp_send_json_error( 'Failed to delete.' );
     907
     908                // VERIFICATION: Pull fresh from DB
     909                $verified_content = get_post_field( 'post_content', $source_id );
     910                if ( strpos( $verified_content, $old_link ) === false ) {
     911                    $updated   = true;
     912                    $details[] = "Verified: Link removed from standard content.";
     913                } else {
     914                    $details[] = "Critical: Link still exists in standard content after update.";
     915                }
     916            }
     917        } else {
     918            $details[] = 'Not found in standard WordPress post content.';
     919        }
     920
     921        // 2. Elementor Data (JSON Meta)
     922        if ( is_plugin_active( 'elementor/elementor.php' ) ) {
     923            $details[] = 'Checking Elementor data meta...';
     924
     925            $elementor_data = get_post_meta( $source_id, '_elementor_data', true );
     926            if ( ! empty( $elementor_data ) ) {
     927                $details[] = 'Found in Elementor data meta.';
     928
     929                $escaped_old = str_replace( '/', '\/', $old_link );
     930                $escaped_new = str_replace( '/', '\/', $new_link );
     931
     932                $found_raw     = ( strpos( $elementor_data, $old_link ) !== false );
     933                $found_escaped = ( strpos( $elementor_data, $escaped_old ) !== false );
     934
     935                if ( $found_raw ) {
     936                    $details[] = 'Old link found in raw form in Elementor data.';
     937                } elseif ( $found_escaped ) {
     938                    $details[] = 'Old link found in escaped form in Elementor data.';
     939                } else {
     940                    $details[] = 'Old link not found in raw or escaped form in Elementor data.';
     941                }
     942
     943                if ( $found_raw || $found_escaped ) {
     944                    $data = str_replace( $old_link, $new_link, $elementor_data );
     945                    $data = str_replace( $escaped_old, $escaped_new, $data );
     946
     947                    $meta_result = update_post_meta( $source_id, '_elementor_data', wp_slash( $data ) );
     948
     949                    if ( $meta_result ) {
     950
     951                        // VERIFICATION: Pull fresh meta
     952                        $verified_meta = get_post_meta( $source_id, '_elementor_data', true );
     953                        if ( strpos( $verified_meta, $old_link ) === false && strpos( $verified_meta, $escaped_old ) === false ) {
     954                            if ( class_exists( '\Elementor\Plugin' ) ) {
     955                                \Elementor\Plugin::$instance->posts_css_manager->clear_cache();
     956                            }
     957                            $updated   = true;
     958                            $details[] = "Verified: Link removed from Elementor metadata.";
     959                        } else {
     960                            $details[] = "Critical: Link still exists in Elementor meta after update.";
     961                        }
     962                    } else {
     963                        $fail_reason = 'Failed to update Elementor meta data.';
     964                    }
     965                } else {
     966                    $fail_reason = 'Link not found in Elementor meta data.';
     967                }
     968            } else {
     969                $fail_reason = 'Not found in Elementor data meta.';
     970            }
     971        }
     972
     973        if ( $updated ) {
     974            $this->remove( $HELPERS->str_replace_on_link( $old_link ), $link_id );
     975
     976            wp_send_json_success( [
     977                'linkID'   => $link_id,
     978                'msg'      => 'Link replaced successfully.',
     979                'details'  => $details
     980            ] );
     981        }
     982
     983        // If we reach here, something went wrong
     984        wp_send_json_error( [ 'msg' => $fail_reason . "\n" . implode( "\n", $details ) ] );
    910985    } // End ajax_replace_link()
    911986
     
    10301105        // Javascript
    10311106        $handle = 'front_end_js';
    1032         wp_register_script( $handle, BLNOTIFIER_PLUGIN_JS_PATH.'results-front.min.js', [ 'jquery' ], BLNOTIFIER_VERSION, true );
     1107        if ( file_exists( BLNOTIFIER_PLUGIN_JS_ABSPATH.'results-front.min.js' ) ) {
     1108            $js_path = BLNOTIFIER_PLUGIN_JS_PATH.'results-front.min.js';
     1109        } else {
     1110            $js_path = BLNOTIFIER_PLUGIN_JS_PATH.'results-front.js';
     1111        }
     1112        wp_register_script( $handle, $js_path, [ 'jquery' ], BLNOTIFIER_VERSION, true );
    10331113        wp_localize_script( $handle, 'blnotifier_front_end', [
    10341114            'show_in_console' => filter_var( get_option( 'blnotifier_show_in_console' ), FILTER_VALIDATE_BOOLEAN ),
  • broken-link-notifier/trunk/readme.txt

    r3486590 r3492911  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.3.7.3
     7Stable tag: 1.3.7.4
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.txt
     
    127127
    128128== Changelog ==
     129= 1.3.7.4 =
     130* Fix: Added support for Elementor when replacing links from results page (props @nazrinn)
     131* Update: Added good links and status on console results
     132
    129133= 1.3.7.3 =
    130134* Fix: Undefined properties
Note: See TracChangeset for help on using the changeset viewer.