problematic_paths(), true ); $settings = C7DBT_Settings::get(); $slug = C7DBT_Helpers::sanitize_slug( $settings['default_collection_slug'] ); foreach ( $menus as $menu ) { $items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) ); if ( ! $items ) { continue; } foreach ( $items as $item ) { $url = $item->url; $path = wp_parse_url( $url, PHP_URL_PATH ); if ( ! is_string( $path ) ) { continue; } $path_norm = untrailingslashit( '/' . trim( $path, '/' ) ); $rel = $this->strip_home_path( $path_norm ); if ( isset( $bad_set[ $rel ] ) || isset( $bad_set[ ltrim( $rel, '/' ) ] ) ) { $issues[] = array( 'menu_id' => (int) $menu->term_id, 'menu_name' => $menu->name, 'item_id' => (int) $item->ID, 'title' => $item->title, 'url' => $url, 'path' => $rel, 'type' => $item->type, 'suggested' => $slug ? home_url( '/collection/' . $slug . '/' ) : '', ); } } } return $issues; } /** * Strip site home path prefix. * * @param string $path Path. * @return string */ private function strip_home_path( $path ) { $home_path = wp_parse_url( home_url( '/' ), PHP_URL_PATH ); if ( is_string( $home_path ) && '/' !== $home_path && 0 === strpos( $path, rtrim( $home_path, '/' ) ) ) { $path = substr( $path, strlen( rtrim( $home_path, '/' ) ) ); if ( '' === $path ) { $path = '/'; } } return untrailingslashit( '/' . trim( $path, '/' ) ); } /** * Fix all found menu items to default collection URL without rebuilding the item. * * @return array{fixed:int,skipped:int,messages:array} */ public function fix_all() { $settings = C7DBT_Settings::get(); $slug = C7DBT_Helpers::sanitize_slug( $settings['default_collection_slug'] ); if ( ! $slug ) { return array( 'fixed' => 0, 'skipped' => 0, 'messages' => array( __( 'Set a default collection slug first.', '7labs-debug-branding-for-commerce7' ) ), ); } $target = home_url( '/collection/' . $slug . '/' ); $issues = $this->find_issues(); $fixed = 0; $skipped = 0; foreach ( $issues as $issue ) { $item_id = (int) $issue['item_id']; if ( $item_id <= 0 || ! get_post( $item_id ) ) { ++$skipped; continue; } // Prefer meta updates so parent/order/classes stay intact (FixSeal-style safety). $ok_url = update_post_meta( $item_id, '_menu_item_url', esc_url_raw( $target ) ); $ok_type = update_post_meta( $item_id, '_menu_item_type', 'custom' ); update_post_meta( $item_id, '_menu_item_object', 'custom' ); update_post_meta( $item_id, '_menu_item_object_id', 0 ); if ( false === $ok_url && false === $ok_type ) { // Meta unchanged is still success if URL already matched after sanitize. $current = get_post_meta( $item_id, '_menu_item_url', true ); if ( untrailingslashit( (string) $current ) === untrailingslashit( $target ) ) { ++$fixed; } else { ++$skipped; } } else { ++$fixed; } clean_post_cache( $item_id ); } // Bust menu caches. foreach ( wp_get_nav_menus() as $menu ) { wp_cache_delete( 'nav_menu_items-' . $menu->term_id, 'nav_menus' ); } return array( 'fixed' => $fixed, 'skipped' => $skipped, 'messages' => array( sprintf( /* translators: 1: fixed count, 2: URL */ __( 'Updated %1$d menu link(s) to %2$s.', '7labs-debug-branding-for-commerce7' ), $fixed, $target ), ), ); } /** * Dashboard status. * * @return array */ public function status() { $issues = $this->find_issues(); $count = count( $issues ); if ( $count > 0 ) { return array( 'status' => 'warn', 'label' => __( 'Broken shop menu links', '7labs-debug-branding-for-commerce7' ), 'detail' => sprintf( /* translators: %d: count */ _n( '%d menu item points to an empty C7 base URL.', '%d menu items point to empty C7 base URLs.', $count, '7labs-debug-branding-for-commerce7' ), $count ), 'count' => $count, ); } return array( 'status' => 'ok', 'label' => __( 'Menu links look OK', '7labs-debug-branding-for-commerce7' ), 'detail' => __( 'No nav items point at empty /collection or /product.', '7labs-debug-branding-for-commerce7' ), 'count' => 0, ); } }