editor = new EditorDetector(); } public function register( Loader $loader ): void {} /** * Finds a WP page that has a specific meta key/value. * Returns the page ID or null if not found. */ protected function find_page_by_meta( string $meta_key, int $meta_value ): ?int { $posts = get_posts( [ 'post_type' => 'page', 'post_status' => [ 'publish', 'draft', 'private' ], 'posts_per_page' => 1, 'fields' => 'ids', 'meta_query' => [ [ 'key' => $meta_key, 'value' => $meta_value, ] ], ] ); return $posts[0] ?? null; } /** * Creates a WP page and returns its ID. * Returns 0 on failure. * * Suppresses WordPress's auto-add-to-nav-menu feature for the duration of * the insert, so individual member / course / project pages never appear * in navigation menus automatically. Archive pages (People, Courses, Projects) * are created directly via wp_insert_post() outside this method and are * therefore unaffected — the site admin controls their menu placement. */ protected function create_page( array $args ): int { // Temporarily clear the auto_add list so WP does not add this page to any menu. $suppress = static function ( array $opts ): array { $opts['auto_add'] = []; return $opts; }; add_filter( 'option_nav_menu_options', $suppress ); $page_id = wp_insert_post( $args, true ); remove_filter( 'option_nav_menu_options', $suppress ); if ( is_wp_error( $page_id ) ) { error_log( 'AcademicCrew PageGenerator: ' . $page_id->get_error_message() ); return 0; } // Belt and braces: strip any menu item a menu with `auto_add` (or a // third-party plugin) still attached to this fresh page. $this->remove_nav_menu_items_for_page( (int) $page_id ); return (int) $page_id; } /** * Permanently removes all nav-menu items that link to the given page. * WordPress does not do this automatically on post deletion. */ protected function remove_nav_menu_items_for_page( int $page_id ): void { $nav_items = get_posts( [ 'post_type' => 'nav_menu_item', 'post_status' => 'any', 'posts_per_page' => -1, 'fields' => 'ids', 'meta_query' => [ [ 'key' => '_menu_item_object_id', 'value' => $page_id, 'type' => 'NUMERIC', ] ], ] ); foreach ( $nav_items as $item_id ) { wp_delete_post( (int) $item_id, true ); } } /** * Standard Fusion Builder notice block prepended to generated page content. */ protected function fusion_lock_notice( string $message ): string { return '[fusion_builder_container][fusion_builder_row]' . '[fusion_builder_column type="1_1"]' . '[fusion_text]' . '
' . '🔒 ' . esc_html( $message ) . '
' . '[/fusion_text]' . '[/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]'; } /** * Standard Gutenberg notice block. */ protected function gutenberg_lock_notice( string $message ): string { return '' . '🔒 ' . esc_html( $message ) . '
' . ''; } }