reserved_slugs() as $slug ) { $page = get_page_by_path( $slug ); if ( ! $page ) { // Also try get_posts by name for non-hierarchical edge cases. $pages = get_posts( array( 'name' => $slug, 'post_type' => 'page', 'post_status' => array( 'publish', 'draft', 'private' ), 'numberposts' => 1, ) ); $page = $pages ? $pages[0] : null; } if ( ! $page ) { continue; } $has_elementor = $this->page_uses_elementor( $page->ID ); $is_critical = in_array( $slug, array( 'checkout', 'cart', 'club' ), true ); if ( $has_elementor && $is_critical ) { $issues[] = array( 'type' => 'elementor_critical', 'severity' => 'error', 'needs_dev' => true, 'slug' => $slug, 'page_id' => (int) $page->ID, 'title' => $page->post_title, 'message' => sprintf( /* translators: %s: slug */ __( 'Page “%s” uses Elementor. Full canvas / heavy builders on checkout, cart, or club often break Commerce7 modals.', '7labs-debug-branding-for-commerce7' ), $slug ), 'fix' => __( 'Use the block editor (or classic) with the Commerce7 default content block on this page.', '7labs-debug-branding-for-commerce7' ), ); } elseif ( $has_elementor ) { $issues[] = array( 'type' => 'elementor_notice', 'severity' => 'warn', 'slug' => $slug, 'page_id' => (int) $page->ID, 'title' => $page->post_title, 'message' => sprintf( /* translators: %s: slug */ __( 'Page “%s” uses Elementor. Ensure the Commerce7 default content placeholder is present.', '7labs-debug-branding-for-commerce7' ), $slug ), 'fix' => __( 'Keep C7 content block intact; avoid nested full-width templates that strip the c7-content mount.', '7labs-debug-branding-for-commerce7' ), ); } } // Missing required pages. foreach ( array( 'collection', 'product', 'cart', 'checkout' ) as $required ) { $page = get_page_by_path( $required ); if ( ! $page ) { $issues[] = array( 'type' => 'missing_page', 'severity' => 'warn', 'slug' => $required, 'page_id' => 0, 'title' => '', 'message' => sprintf( /* translators: %s: slug */ __( 'Required Commerce7 route page “/%s” was not found on this site.', '7labs-debug-branding-for-commerce7' ), $required ), 'fix' => __( 'Create a published page with that exact slug and the Commerce7 default content block (or ask your developer to restore the standard shop pages).', '7labs-debug-branding-for-commerce7' ), ); } } // Permalink structure. $structure = get_option( 'permalink_structure' ); if ( empty( $structure ) ) { $issues[] = array( 'type' => 'permalinks', 'severity' => 'error', 'slug' => '', 'page_id' => 0, 'title' => '', 'message' => __( 'Pretty permalinks are disabled. Commerce7 dynamic routes need Post name (or similar) permalinks.', '7labs-debug-branding-for-commerce7' ), 'fix' => __( 'Go to Settings → Permalinks, choose Post name, and Save.', '7labs-debug-branding-for-commerce7' ), ); } // Subfolder install warning. $home_path = wp_parse_url( home_url( '/' ), PHP_URL_PATH ); if ( is_string( $home_path ) && $home_path && '/' !== $home_path ) { $issues[] = array( 'type' => 'subfolder', 'severity' => 'error', 'needs_dev' => true, 'slug' => '', 'page_id' => 0, 'title' => '', 'message' => __( 'WordPress appears to be in a subfolder. Commerce7 generally requires a root domain or subdomain install.', '7labs-debug-branding-for-commerce7' ), 'fix' => __( 'Move WordPress to the domain root or a subdomain (e.g. shop.example.com), not /wordpress/.', '7labs-debug-branding-for-commerce7' ), ); } if ( ! C7DBT_Helpers::is_c7wp_active() ) { $issues[] = array( 'type' => 'missing_c7wp', 'severity' => 'error', 'slug' => '', 'page_id' => 0, 'title' => '', 'message' => __( 'Commerce7 does not appear to be connected on this site.', '7labs-debug-branding-for-commerce7' ), 'fix' => __( 'Add your Commerce7 tenant ID in your site’s Commerce7 integration settings, then confirm shop route pages exist.', '7labs-debug-branding-for-commerce7' ), ); } $issues = array_merge( $issues, $this->find_plugin_conflicts() ); return $issues; } /** * Active plugins that commonly conflict with Commerce7 routes or checkout. * * @return array */ private function find_plugin_conflicts() { $issues = array(); $cache = $this->first_active_plugin( array( 'litespeed-cache/litespeed-cache.php' => 'LiteSpeed Cache', 'wp-rocket/wp-rocket.php' => 'WP Rocket', 'w3-total-cache/w3-total-cache.php' => 'W3 Total Cache', 'wp-super-cache/wp-cache.php' => 'WP Super Cache', 'wp-fastest-cache/wpFastestCache.php' => 'WP Fastest Cache', 'autoptimize/autoptimize.php' => 'Autoptimize', 'sg-cachepress/sg-cachepress.php' => 'SiteGround Optimizer', 'cloudflare/cloudflare.php' => 'Cloudflare', ) ); if ( $cache ) { $issues[] = array( 'type' => 'cache_plugin', 'severity' => 'warn', 'needs_dev' => true, 'slug' => '', 'page_id' => 0, 'title' => $cache['name'], 'message' => sprintf( /* translators: %s: plugin name */ __( '%s is active. Cart, checkout, and club pages must be excluded from full-page cache or Commerce7 modals can fail.', '7labs-debug-branding-for-commerce7' ), $cache['name'] ), 'fix' => __( 'Exclude /cart, /checkout, /club, and /collection/* from cache — or ask your developer to configure cache rules.', '7labs-debug-branding-for-commerce7' ), ); } $redirect = $this->first_active_plugin( array( 'redirection/redirection.php' => 'Redirection', 'seo-by-rank-math/rank-math.php' => 'Rank Math SEO', 'wordpress-seo/wp-seo.php' => 'Yoast SEO', 'all-in-one-seo-pack/all_in_one_seo_pack.php' => 'All in One SEO', ) ); if ( $redirect ) { $issues[] = array( 'type' => 'redirect_plugin', 'severity' => 'warn', 'needs_dev' => true, 'slug' => '', 'page_id' => 0, 'title' => $redirect['name'], 'message' => sprintf( /* translators: %s: plugin name */ __( '%s can add redirects that override /collection or shop URLs. Review rules after changing your collection slug.', '7labs-debug-branding-for-commerce7' ), $redirect['name'] ), 'fix' => __( 'Audit redirect rules so /collection and your live shop slug are not caught by old SEO redirects.', '7labs-debug-branding-for-commerce7' ), ); } $multilingual = $this->first_active_plugin( array( 'sitepress-multilingual-cms/sitepress-multilingual-cms.php' => 'WPML', 'polylang/polylang.php' => 'Polylang', 'polylang-pro/polylang.php' => 'Polylang Pro', 'translatepress-multilingual/index.php' => 'TranslatePress', ) ); if ( $multilingual ) { $issues[] = array( 'type' => 'multilingual', 'severity' => 'warn', 'needs_dev' => true, 'slug' => '', 'page_id' => 0, 'title' => $multilingual['name'], 'message' => sprintf( /* translators: %s: plugin name */ __( '%s is active. Multilingual setups often rewrite Commerce7 route URLs (/collection, /product, /checkout).', '7labs-debug-branding-for-commerce7' ), $multilingual['name'] ), 'fix' => __( 'Confirm each language has working shop URLs and that C7 pages are not duplicated with wrong slugs.', '7labs-debug-branding-for-commerce7' ), ); } $consent = $this->first_active_plugin( array( 'age-gate/age-gate.php' => 'Age Gate', 'cookie-law-info/cookie-law-info.php' => 'CookieYes (Cookie Law Info)', 'complianz-gdpr/complianz-gpdr.php' => 'Complianz', 'gdpr-cookie-compliance/moove-gdpr.php' => 'GDPR Cookie Compliance', 'cookie-notice/cookie-notice.php' => 'Cookie Notice', ) ); if ( $consent ) { $issues[] = array( 'type' => 'consent_gate', 'severity' => 'warn', 'needs_dev' => true, 'slug' => '', 'page_id' => 0, 'title' => $consent['name'], 'message' => sprintf( /* translators: %s: plugin name */ __( '%s is active. Age gates and cookie banners can block Commerce7 scripts until configured correctly.', '7labs-debug-branding-for-commerce7' ), $consent['name'] ), 'fix' => __( 'Allow Commerce7 scripts before the gate fires on shop pages, or test Add to Cart in a private window.', '7labs-debug-branding-for-commerce7' ), ); } return $issues; } /** * Return first active plugin from a map of file => label. * * @param array $map Plugin file => human name. * @return array|null */ private function first_active_plugin( array $map ) { if ( ! function_exists( 'is_plugin_active' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } foreach ( $map as $file => $name ) { if ( is_plugin_active( $file ) ) { return array( 'file' => $file, 'name' => $name, ); } } return null; } /** * Detect Elementor usage on a page. * * @param int $post_id Post ID. * @return bool */ private function page_uses_elementor( $post_id ) { $edit_mode = get_post_meta( $post_id, '_elementor_edit_mode', true ); if ( 'builder' === $edit_mode ) { return true; } $data = get_post_meta( $post_id, '_elementor_data', true ); return ! empty( $data ); } /** * Dashboard status. * * @return array */ public function status() { $issues = $this->find_issues(); $errors = array_filter( $issues, static function ( $i ) { return 'error' === $i['severity']; } ); $count = count( $issues ); if ( count( $errors ) > 0 ) { return array( 'status' => 'error', 'label' => __( 'Integration conflicts found', '7labs-debug-branding-for-commerce7' ), 'detail' => sprintf( /* translators: %d: count */ _n( '%d issue needs attention.', '%d issues need attention.', $count, '7labs-debug-branding-for-commerce7' ), $count ), 'count' => $count, ); } if ( $count > 0 ) { return array( 'status' => 'warn', 'label' => __( 'Minor conflicts', '7labs-debug-branding-for-commerce7' ), 'detail' => sprintf( /* translators: %d: count */ _n( '%d warning.', '%d warnings.', $count, '7labs-debug-branding-for-commerce7' ), $count ), 'count' => $count, ); } return array( 'status' => 'ok', 'label' => __( 'No route conflicts detected', '7labs-debug-branding-for-commerce7' ), 'detail' => __( 'Required pages and permalinks look healthy.', '7labs-debug-branding-for-commerce7' ), 'count' => 0, ); } }