Changeset 3771047
- Timestamp:
- 10/28/2026 04:14:21 PM (21 hours ago)
- Location:
- crawlsure
- Files:
-
- 14 edited
- 1 copied
-
tags/0.8.5 (copied) (copied from crawlsure/trunk )
-
tags/0.8.5/crawlsure.php (modified) (2 diffs)
-
tags/0.8.5/includes/class-crawlsure-admin-links.php (modified) (1 diff)
-
tags/0.8.5/includes/class-crawlsure-indexing.php (modified) (3 diffs)
-
tags/0.8.5/includes/class-crawlsure-links.php (modified) (4 diffs)
-
tags/0.8.5/includes/class-crawlsure-pages.php (modified) (2 diffs)
-
tags/0.8.5/includes/class-crawlsure-plugin.php (modified) (1 diff)
-
tags/0.8.5/readme.txt (modified) (2 diffs)
-
trunk/crawlsure.php (modified) (2 diffs)
-
trunk/includes/class-crawlsure-admin-links.php (modified) (1 diff)
-
trunk/includes/class-crawlsure-indexing.php (modified) (3 diffs)
-
trunk/includes/class-crawlsure-links.php (modified) (4 diffs)
-
trunk/includes/class-crawlsure-pages.php (modified) (2 diffs)
-
trunk/includes/class-crawlsure-plugin.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
crawlsure/tags/0.8.5/crawlsure.php
r3771007 r3771047 4 4 * Plugin URI: https://www.wordpromise.com/crawlsure/ 5 5 * Description: Technical SEO and AI search for WordPress. Finds what holds your site back, explains it in plain English and fixes it. 6 * Version: 0.8. 46 * Version: 0.8.5 7 7 * Requires at least: 6.5 8 8 * Requires PHP: 7.4 … … 18 18 defined( 'ABSPATH' ) || exit; 19 19 20 define( 'CRAWLSURE_VERSION', '0.8. 4' );20 define( 'CRAWLSURE_VERSION', '0.8.5' ); 21 21 define( 'CRAWLSURE_FILE', __FILE__ ); 22 22 define( 'CRAWLSURE_DIR', plugin_dir_path( __FILE__ ) ); -
crawlsure/tags/0.8.5/includes/class-crawlsure-admin-links.php
r3771007 r3771047 186 186 . esc_html( sprintf( _n( 'Remove %d dead link', 'Remove all %d dead links', $dead, 'crawlsure' ), $dead ) ) . '</a> <span class="description">' 187 187 . esc_html__( 'Only links to other websites whose page or whole website is gone, seen on two checks a day apart. Server errors and links to your own site are left for you to decide.', 'crawlsure' ) . '</span></p>'; 188 } elseif ( $on && $problems ) { 189 echo '<p class="description cs-bulk">' . esc_html__( 'Nothing to remove in one go right now. "Remove all dead links" appears when links to other websites are certainly dead (the page or whole website is gone, seen on two checks a day apart). The links below are on your own site (better redirected), may be down only for now, or were found once so far: remove them one by one with "Remove link", or check them again later.', 'crawlsure' ) . '</p>'; 188 190 } 189 191 if ( ! $on ) { -
crawlsure/tags/0.8.5/includes/class-crawlsure-indexing.php
r3768686 r3771047 104 104 */ 105 105 public static function post_types() { 106 return array_values( array_diff( get_post_types( array( 'public' => true ) ), array( 'attachment' ) ));106 return Crawlsure_Plugin::content_types(); 107 107 } 108 108 … … 326 326 public static function stats() { 327 327 global $wpdb; 328 self::prune(); 328 329 $table = Crawlsure_DB::table( 'gsc_index' ); 329 330 $row = $wpdb->get_row( $wpdb->prepare( "SELECT COUNT(*) AS checked, SUM(verdict = 'pass') AS indexed, SUM(verdict <> 'pass' AND error = '') AS nots, SUM(error <> '') AS errors FROM %i", $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery … … 348 349 'total' => $total, 349 350 ); 351 } 352 353 /** 354 * Forget results for posts that are gone or are not real pages (for example page-builder templates 355 * checked by earlier versions). 356 */ 357 public static function prune() { 358 Crawlsure_Plugin::prune_rows( Crawlsure_DB::table( 'gsc_index' ) ); 350 359 } 351 360 -
crawlsure/tags/0.8.5/includes/class-crawlsure-links.php
r3771007 r3771047 61 61 */ 62 62 public static function post_types() { 63 return array_values( array_diff( get_post_types( array( 'public' => true ) ), array( 'attachment' ) ));63 return Crawlsure_Plugin::content_types(); 64 64 } 65 65 … … 235 235 236 236 /** 237 * Forget the links of posts that are gone or are not real pages (for example page-builder templates 238 * indexed by earlier versions), and the links no page uses any more. 239 */ 240 public static function prune_refs() { 241 global $wpdb; 242 Crawlsure_Plugin::prune_rows( self::link_refs_table() ); 243 $wpdb->query( $wpdb->prepare( 'DELETE l FROM %i l LEFT JOIN %i r ON r.link_id = l.id WHERE r.link_id IS NULL', Crawlsure_DB::table( 'links' ), self::link_refs_table() ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery 244 } 245 246 /** 247 * The table of which page uses which link. 248 * 249 * @return string 250 */ 251 private static function link_refs_table() { 252 return Crawlsure_DB::table( 'link_refs' ); 253 } 254 255 /** 237 256 * Remove a post's links from the index. 238 257 * … … 294 313 $links = Crawlsure_DB::table( 'links' ); 295 314 $refs = Crawlsure_DB::table( 'link_refs' ); 315 self::prune_refs(); 296 316 // Links no longer used anywhere are dropped. 297 317 $wpdb->query( $wpdb->prepare( 'DELETE l FROM %i l LEFT JOIN %i r ON r.link_id = l.id WHERE r.link_id IS NULL', $links, $refs ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery … … 470 490 public static function stats() { 471 491 global $wpdb; 492 self::prune_refs(); 472 493 $t = Crawlsure_DB::table( 'links' ); 473 494 $row = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -
crawlsure/tags/0.8.5/includes/class-crawlsure-pages.php
r3768686 r3771047 121 121 $limit = is_numeric( $limit ) && (int) $limit > 0 ? (int) $limit : self::BATCH; 122 122 $table = Crawlsure_DB::table( 'page_checks' ); 123 Crawlsure_Plugin::prune_rows( $table ); 123 124 self::sync(); 124 125 $site = get_option( self::SITE_OPTION ); … … 732 733 global $wpdb; 733 734 $table = Crawlsure_DB::table( 'page_checks' ); 735 Crawlsure_Plugin::prune_rows( $table ); 734 736 $pages = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i', $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery 735 737 $checked = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i WHERE checked IS NOT NULL AND status > 0', $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -
crawlsure/tags/0.8.5/includes/class-crawlsure-plugin.php
r3768686 r3771047 169 169 170 170 /** 171 * Content types with real public pages: the ones WordPress lists for its own sitemap (public and 172 * viewable, minus what plugins take out through wp_sitemaps_post_types, as Elementor does with its 173 * template library), without page-builder template types that slip through. Used by the link 174 * checker, page checks and the "In Google" check, so templates and saved layouts are never checked. 175 * 176 * @return string[] 177 */ 178 public static function content_types() { 179 $objects = array(); 180 foreach ( get_post_types( array( 'public' => true ), 'objects' ) as $name => $object ) { 181 if ( 'attachment' !== $name && is_post_type_viewable( $object ) ) { 182 $objects[ $name ] = $object; 183 } 184 } 185 $objects = (array) apply_filters( 'wp_sitemaps_post_types', $objects ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- core hook, read the way WordPress's sitemap reads it. 186 $types = array_diff( 187 array_keys( $objects ), 188 array( 'elementor_library', 'e-floating-buttons', 'elementor-hf', 'et_pb_layout', 'fl-builder-template', 'ct_template', 'oxy_user_library', 'bricks_template', 'brizy_template', 'kadence_element', 'astra-advanced-hook', 'wp_block', 'wp_template', 'wp_template_part', 'wp_navigation' ) 189 ); 190 /** 191 * Filter the content types Crawlsure checks (links, page checks, "In Google"). 192 * 193 * @param string[] $types Post type names. 194 */ 195 return array_values( (array) apply_filters( 'crawlsure_content_types', array_values( $types ) ) ); 196 } 197 198 /** 199 * Delete a Crawlsure table's rows (keyed by post_id) for posts that are gone or are not real pages. 200 * 201 * @param string $table Full table name. 202 */ 203 public static function prune_rows( $table ) { 204 global $wpdb; 205 $types = self::content_types(); 206 if ( ! $types ) { 207 return; 208 } 209 $wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery 210 $wpdb->prepare( 211 'DELETE t FROM %i t LEFT JOIN %i p ON p.ID = t.post_id WHERE p.ID IS NULL OR p.post_type NOT IN (' . implode( ',', array_fill( 0, count( $types ), '%s' ) ) . ')', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.NotPrepared -- one placeholder per type. 212 array_merge( array( $table, $wpdb->posts ), $types ) 213 ) 214 ); 215 } 216 217 /** 171 218 * Main category of a post: the one chosen in Crawlsure if the post is still in it, 172 219 * otherwise WordPress's first category. Null for posts without categories. -
crawlsure/tags/0.8.5/readme.txt
r3771007 r3771047 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 0.8. 47 Stable tag: 0.8.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 108 108 == Changelog == 109 109 110 = 0.8.5 = 111 * Page-builder templates (Elementor templates, saved layouts, headers and footers and the like) are no longer treated as pages: they are left out of the link checker, the page checks and the "In Google" check, and old results for them are cleared. Crawlsure now checks the same content types WordPress puts in its sitemap. 112 * Links and 404s: when nothing can be removed in one go, a short note explains why and what to do instead. 113 110 114 = 0.8.4 = 111 115 * Simpler menu: the WordPress sidebar now shows one line per section (Overview, Checks, Search and AI, Your site, Tools, Settings) instead of every page; the Crawlsure header leads to the pages of each section. Setup and Import moved to the new Settings section. -
crawlsure/trunk/crawlsure.php
r3771007 r3771047 4 4 * Plugin URI: https://www.wordpromise.com/crawlsure/ 5 5 * Description: Technical SEO and AI search for WordPress. Finds what holds your site back, explains it in plain English and fixes it. 6 * Version: 0.8. 46 * Version: 0.8.5 7 7 * Requires at least: 6.5 8 8 * Requires PHP: 7.4 … … 18 18 defined( 'ABSPATH' ) || exit; 19 19 20 define( 'CRAWLSURE_VERSION', '0.8. 4' );20 define( 'CRAWLSURE_VERSION', '0.8.5' ); 21 21 define( 'CRAWLSURE_FILE', __FILE__ ); 22 22 define( 'CRAWLSURE_DIR', plugin_dir_path( __FILE__ ) ); -
crawlsure/trunk/includes/class-crawlsure-admin-links.php
r3771007 r3771047 186 186 . esc_html( sprintf( _n( 'Remove %d dead link', 'Remove all %d dead links', $dead, 'crawlsure' ), $dead ) ) . '</a> <span class="description">' 187 187 . esc_html__( 'Only links to other websites whose page or whole website is gone, seen on two checks a day apart. Server errors and links to your own site are left for you to decide.', 'crawlsure' ) . '</span></p>'; 188 } elseif ( $on && $problems ) { 189 echo '<p class="description cs-bulk">' . esc_html__( 'Nothing to remove in one go right now. "Remove all dead links" appears when links to other websites are certainly dead (the page or whole website is gone, seen on two checks a day apart). The links below are on your own site (better redirected), may be down only for now, or were found once so far: remove them one by one with "Remove link", or check them again later.', 'crawlsure' ) . '</p>'; 188 190 } 189 191 if ( ! $on ) { -
crawlsure/trunk/includes/class-crawlsure-indexing.php
r3768686 r3771047 104 104 */ 105 105 public static function post_types() { 106 return array_values( array_diff( get_post_types( array( 'public' => true ) ), array( 'attachment' ) ));106 return Crawlsure_Plugin::content_types(); 107 107 } 108 108 … … 326 326 public static function stats() { 327 327 global $wpdb; 328 self::prune(); 328 329 $table = Crawlsure_DB::table( 'gsc_index' ); 329 330 $row = $wpdb->get_row( $wpdb->prepare( "SELECT COUNT(*) AS checked, SUM(verdict = 'pass') AS indexed, SUM(verdict <> 'pass' AND error = '') AS nots, SUM(error <> '') AS errors FROM %i", $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery … … 348 349 'total' => $total, 349 350 ); 351 } 352 353 /** 354 * Forget results for posts that are gone or are not real pages (for example page-builder templates 355 * checked by earlier versions). 356 */ 357 public static function prune() { 358 Crawlsure_Plugin::prune_rows( Crawlsure_DB::table( 'gsc_index' ) ); 350 359 } 351 360 -
crawlsure/trunk/includes/class-crawlsure-links.php
r3771007 r3771047 61 61 */ 62 62 public static function post_types() { 63 return array_values( array_diff( get_post_types( array( 'public' => true ) ), array( 'attachment' ) ));63 return Crawlsure_Plugin::content_types(); 64 64 } 65 65 … … 235 235 236 236 /** 237 * Forget the links of posts that are gone or are not real pages (for example page-builder templates 238 * indexed by earlier versions), and the links no page uses any more. 239 */ 240 public static function prune_refs() { 241 global $wpdb; 242 Crawlsure_Plugin::prune_rows( self::link_refs_table() ); 243 $wpdb->query( $wpdb->prepare( 'DELETE l FROM %i l LEFT JOIN %i r ON r.link_id = l.id WHERE r.link_id IS NULL', Crawlsure_DB::table( 'links' ), self::link_refs_table() ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery 244 } 245 246 /** 247 * The table of which page uses which link. 248 * 249 * @return string 250 */ 251 private static function link_refs_table() { 252 return Crawlsure_DB::table( 'link_refs' ); 253 } 254 255 /** 237 256 * Remove a post's links from the index. 238 257 * … … 294 313 $links = Crawlsure_DB::table( 'links' ); 295 314 $refs = Crawlsure_DB::table( 'link_refs' ); 315 self::prune_refs(); 296 316 // Links no longer used anywhere are dropped. 297 317 $wpdb->query( $wpdb->prepare( 'DELETE l FROM %i l LEFT JOIN %i r ON r.link_id = l.id WHERE r.link_id IS NULL', $links, $refs ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery … … 470 490 public static function stats() { 471 491 global $wpdb; 492 self::prune_refs(); 472 493 $t = Crawlsure_DB::table( 'links' ); 473 494 $row = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -
crawlsure/trunk/includes/class-crawlsure-pages.php
r3768686 r3771047 121 121 $limit = is_numeric( $limit ) && (int) $limit > 0 ? (int) $limit : self::BATCH; 122 122 $table = Crawlsure_DB::table( 'page_checks' ); 123 Crawlsure_Plugin::prune_rows( $table ); 123 124 self::sync(); 124 125 $site = get_option( self::SITE_OPTION ); … … 732 733 global $wpdb; 733 734 $table = Crawlsure_DB::table( 'page_checks' ); 735 Crawlsure_Plugin::prune_rows( $table ); 734 736 $pages = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i', $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery 735 737 $checked = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i WHERE checked IS NOT NULL AND status > 0', $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -
crawlsure/trunk/includes/class-crawlsure-plugin.php
r3768686 r3771047 169 169 170 170 /** 171 * Content types with real public pages: the ones WordPress lists for its own sitemap (public and 172 * viewable, minus what plugins take out through wp_sitemaps_post_types, as Elementor does with its 173 * template library), without page-builder template types that slip through. Used by the link 174 * checker, page checks and the "In Google" check, so templates and saved layouts are never checked. 175 * 176 * @return string[] 177 */ 178 public static function content_types() { 179 $objects = array(); 180 foreach ( get_post_types( array( 'public' => true ), 'objects' ) as $name => $object ) { 181 if ( 'attachment' !== $name && is_post_type_viewable( $object ) ) { 182 $objects[ $name ] = $object; 183 } 184 } 185 $objects = (array) apply_filters( 'wp_sitemaps_post_types', $objects ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- core hook, read the way WordPress's sitemap reads it. 186 $types = array_diff( 187 array_keys( $objects ), 188 array( 'elementor_library', 'e-floating-buttons', 'elementor-hf', 'et_pb_layout', 'fl-builder-template', 'ct_template', 'oxy_user_library', 'bricks_template', 'brizy_template', 'kadence_element', 'astra-advanced-hook', 'wp_block', 'wp_template', 'wp_template_part', 'wp_navigation' ) 189 ); 190 /** 191 * Filter the content types Crawlsure checks (links, page checks, "In Google"). 192 * 193 * @param string[] $types Post type names. 194 */ 195 return array_values( (array) apply_filters( 'crawlsure_content_types', array_values( $types ) ) ); 196 } 197 198 /** 199 * Delete a Crawlsure table's rows (keyed by post_id) for posts that are gone or are not real pages. 200 * 201 * @param string $table Full table name. 202 */ 203 public static function prune_rows( $table ) { 204 global $wpdb; 205 $types = self::content_types(); 206 if ( ! $types ) { 207 return; 208 } 209 $wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery 210 $wpdb->prepare( 211 'DELETE t FROM %i t LEFT JOIN %i p ON p.ID = t.post_id WHERE p.ID IS NULL OR p.post_type NOT IN (' . implode( ',', array_fill( 0, count( $types ), '%s' ) ) . ')', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.NotPrepared -- one placeholder per type. 212 array_merge( array( $table, $wpdb->posts ), $types ) 213 ) 214 ); 215 } 216 217 /** 171 218 * Main category of a post: the one chosen in Crawlsure if the post is still in it, 172 219 * otherwise WordPress's first category. Null for posts without categories. -
crawlsure/trunk/readme.txt
r3771007 r3771047 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 0.8. 47 Stable tag: 0.8.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 108 108 == Changelog == 109 109 110 = 0.8.5 = 111 * Page-builder templates (Elementor templates, saved layouts, headers and footers and the like) are no longer treated as pages: they are left out of the link checker, the page checks and the "In Google" check, and old results for them are cleared. Crawlsure now checks the same content types WordPress puts in its sitemap. 112 * Links and 404s: when nothing can be removed in one go, a short note explains why and what to do instead. 113 110 114 = 0.8.4 = 111 115 * Simpler menu: the WordPress sidebar now shows one line per section (Overview, Checks, Search and AI, Your site, Tools, Settings) instead of every page; the Crawlsure header leads to the pages of each section. Setup and Import moved to the new Settings section.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)