le || $indexable->object_type !== 'post' ) { return; } $this->update_relations( $this->post->get_post( $post_id ) ); $this->update_has_public_posts( $indexable ); $this->hierarchy_repository->clear_ancestors( $indexable->id ); $this->link_builder->delete( $indexable ); $indexable->delete(); \do_action( 'wpseo_indexable_deleted', $indexable ); } /** * Updates the relations when the post indexable is built. * * @param Indexable $indexable The indexable. * @param WP_Post $post The post. * * @return void */ public function updated_indexable( $indexable, $post ) { // Only interested in post indexables. if ( $indexable->object_type !== 'post' ) { return; } if ( \is_a( $post, Indexable::class ) ) { \_deprecated_argument( __FUNCTION__, '17.7', 'The $old_indexable argument has been deprecated.' ); $post = $this->post->get_post( $indexable->object_id ); } $this->update_relations( $post ); } /** * Saves post meta. * * @param int $post_id Post ID. * * @return void */ public function build_indexable( $post_id ) { // Bail if this is a multisite installation and the site has been switched. if ( $this->is_multisite_and_switched() ) { return; } try { $indexable = $this->repository->find_by_id_and_type( $post_id, 'post', false ); $indexable = $this->builder->build_for_id_and_type( $post_id, 'post', $indexable ); $post = $this->post->get_post( $post_id ); /* * Update whether an author has public posts. * For example this post could be set to Draft or Private, * which can influence if its author has any public posts at all. */ if ( $indexable ) { $this->update_has_public_posts( $indexable ); } // Build links for this post. if ( $post && $indexable && \in_array( $post->post_status, $this->post->get_public_post_statuses(), true ) ) { $this->link_builder->build( $indexable, $post->post_content ); // Save indexable to persist the updated link count. $this->indexable_helper->save_indexable( $indexable ); $this->updated_indexable( $indexable, $post ); } } catch ( Exception $exception ) { $this->logger->log( LogLevel::ERROR, $exception->getMessage() ); } } /** * Updates the has_public_posts when the post indexable is built. * * @param Indexable $indexable The indexable to check. * * @return void */ protected function update_has_public_posts( $indexable ) { // Update the author indexable's has public posts value. try { $author_indexable = $this->repository->find_by_id_and_type( $indexable->author_id, 'user' ); if ( $author_indexable ) { $author_indexable->has_public_posts = $this->author_archive->author_has_public_posts( $author_indexable->object_id ); $this->indexable_helper->save_indexable( $author_indexable ); if ( $this->indexable_helper->should_index_indexable( $author_indexable ) ) { $this->reschedule_cleanup_if_author_has_no_posts( $author_indexable ); } } } catch ( Exception $exception ) { $this->logger->log( LogLevel::ERROR, $exception->getMessage() ); } // Update possible attachment's has public posts value. $this->post->update_has_public_posts_on_attachments( $indexable->object_id, $indexable->is_public ); } /** * Reschedule indexable cleanup if the author does not have any public posts. * This should remove the author from the indexable table, since we do not * want to store authors without public facing posts in the table. * * @param Indexable $author_indexable The author indexable. * * @return void */ protected function reschedule_cleanup_if_author_has_no_posts( $author_indexable ) { if ( $author_indexable->has_public_posts === false ) { $cleanup_not_yet_scheduled = ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ); if ( $cleanup_not_yet_scheduled ) { \wp_schedule_single_event( ( \time() + ( \MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); } } } /** * Updates the relations on post save or post status change. * * @param WP_Post $post The post that has been updated. * * @return void */ protected function update_relations( $post ) { $related_indexables = $this->get_related_indexables( $post ); foreach ( $related_indexables as $indexable ) { // Ignore everything that is not an actual indexable. if ( \is_a( $indexable, Indexable::class ) ) { $indexable->object_last_modified = \max( $indexable->object_last_modified, $post->post_modified_gmt ); $this->indexable_helper->save_indexable( $indexable ); } } } /** * Retrieves the related indexables for given post. * * @param WP_Post $post The post to get the indexables for. * * @return Indexable[] The indexables. */ protected function get_related_indexables( $post ) { /** * The related indexables. * * @var Indexable[] $related_indexables */ $related_indexables = []; $related_indexables[] = $this->repository->find_by_id_and_type( $post->post_author, 'user', false ); $related_indexables[] = $this->repository->find_for_post_type_archive( $post->post_type, false ); $related_indexables[] = $this->repository->find_for_home_page( false ); $taxonomies = \get_post_taxonomies( $post->ID ); $taxonomies = \array_filter( $taxonomies, 'is_taxonomy_viewable' ); $term_ids = []; foreach ( $taxonomies as $taxonomy ) { $terms = \get_the_terms( $post->ID, $taxonomy ); if ( empty( $terms ) || \is_wp_error( $terms ) ) { continue; } $term_ids = \array_merge( $term_ids, \wp_list_pluck( $terms, 'term_id' ) ); } $related_indexables = \array_merge( $related_indexables, $this->repository->find_by_multiple_ids_and_type( $term_ids, 'term', false ) ); return \array_filter( $related_indexables ); } /** * Tests if the site is multisite and switched. * * @return bool True when the site is multisite and switched */ protected function is_multisite_and_switched() { return \is_multisite() && \ms_is_switched(); } } le || $indexable->object_type !== 'post' ) { return; } $this->update_relations( $this->post->get_post( $post_id ) ); $this->update_has_public_posts( $indexable ); $this->hierarchy_repository->clear_ancestors( $indexable->id ); $this->link_builder->delete( $indexable ); $indexable->delete(); \do_action( 'wpseo_indexable_deleted', $indexable ); } /** * Updates the relations when the post indexable is built. * * @param Indexable $indexable The indexable. * @param WP_Post $post The post. * * @return void */ public function updated_indexable( $indexable, $post ) { // Only interested in post indexables. if ( $indexable->object_type !== 'post' ) { return; } if ( \is_a( $post, Indexable::class ) ) { \_deprecated_argument( __FUNCTION__, '17.7', 'The $old_indexable argument has been deprecated.' ); $post = $this->post->get_post( $indexable->object_id ); } $this->update_relations( $post ); } /** * Saves post meta. * * @param int $post_id Post ID. * * @return void */ public function build_indexable( $post_id ) { // Bail if this is a multisite installation and the site has been switched. if ( $this->is_multisite_and_switched() ) { return; } try { $indexable = $this->repository->find_by_id_and_type( $post_id, 'post', false ); $indexable = $this->builder->build_for_id_and_type( $post_id, 'post', $indexable ); $post = $this->post->get_post( $post_id ); /* * Update whether an author has public posts. * For example this post could be set to Draft or Private, * which can influence if its author has any public posts at all. */ if ( $indexable ) { $this->update_has_public_posts( $indexable ); } // Build links for this post. if ( $post && $indexable && \in_array( $post->post_status, $this->post->get_public_post_statuses(), true ) ) { $this->link_builder->build( $indexable, $post->post_content ); // Save indexable to persist the updated link count. $this->indexable_helper->save_indexable( $indexable ); $this->updated_indexable( $indexable, $post ); } } catch ( Exception $exception ) { $this->logger->log( LogLevel::ERROR, $exception->getMessage() ); } } /** * Updates the has_public_posts when the post indexable is built. * * @param Indexable $indexable The indexable to check. * * @return void */ protected function update_has_public_posts( $indexable ) { // Update the author indexable's has public posts value. try { $author_indexable = $this->repository->find_by_id_and_type( $indexable->author_id, 'user' ); if ( $author_indexable ) { $author_indexable->has_public_posts = $this->author_archive->author_has_public_posts( $author_indexable->object_id ); $this->indexable_helper->save_indexable( $author_indexable ); if ( $this->indexable_helper->should_index_indexable( $author_indexable ) ) { $this->reschedule_cleanup_if_author_has_no_posts( $author_indexable ); } } } catch ( Exception $exception ) { $this->logger->log( LogLevel::ERROR, $exception->getMessage() ); } // Update possible attachment's has public posts value. $this->post->update_has_public_posts_on_attachments( $indexable->object_id, $indexable->is_public ); } /** * Reschedule indexable cleanup if the author does not have any public posts. * This should remove the author from the indexable table, since we do not * want to store authors without public facing posts in the table. * * @param Indexable $author_indexable The author indexable. * * @return void */ protected function reschedule_cleanup_if_author_has_no_posts( $author_indexable ) { if ( $author_indexable->has_public_posts === false ) { $cleanup_not_yet_scheduled = ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ); if ( $cleanup_not_yet_scheduled ) { \wp_schedule_single_event( ( \time() + ( \MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); } } } /** * Updates the relations on post save or post status change. * * @param WP_Post $post The post that has been updated. * * @return void */ protected function update_relations( $post ) { $related_indexables = $this->get_related_indexables( $post ); foreach ( $related_indexables as $indexable ) { // Ignore everything that is not an actual indexable. if ( \is_a( $indexable, Indexable::class ) ) { $indexable->object_last_modified = \max( $indexable->object_last_modified, $post->post_modified_gmt ); $this->indexable_helper->save_indexable( $indexable ); } } } /** * Retrieves the related indexables for given post. * * @param WP_Post $post The post to get the indexables for. * * @return Indexable[] The indexables. */ protected function get_related_indexables( $post ) { /** * The related indexables. * * @var Indexable[] $related_indexables */ $related_indexables = []; $related_indexables[] = $this->repository->find_by_id_and_type( $post->post_author, 'user', false ); $related_indexables[] = $this->repository->find_for_post_type_archive( $post->post_type, false ); $related_indexables[] = $this->repository->find_for_home_page( false ); $taxonomies = \get_post_taxonomies( $post->ID ); $taxonomies = \array_filter( $taxonomies, 'is_taxonomy_viewable' ); $term_ids = []; foreach ( $taxonomies as $taxonomy ) { $terms = \get_the_terms( $post->ID, $taxonomy ); if ( empty( $terms ) || \is_wp_error( $terms ) ) { continue; } $term_ids = \array_merge( $term_ids, \wp_list_pluck( $terms, 'term_id' ) ); } $related_indexables = \array_merge( $related_indexables, $this->repository->find_by_multiple_ids_and_type( $term_ids, 'term', false ) ); return \array_filter( $related_indexables ); } /** * Tests if the site is multisite and switched. * * @return bool True when the site is multisite and switched */ protected function is_multisite_and_switched() { return \is_multisite() && \ms_is_switched(); } } Patent Bar Exam Prep Course | 81% Pass Rate - Wysebridge Patent Bar Review

Pass the USPTO Patent Bar Exam in 2026 in half the time for half the cost.

Join the Thousands of Students with a 35% higher chance of passing the Patent Bar Exam the first time with Wysebridge.com 
Over 50% of all exam takers in 2025 failed. Be in the top 50% and pass on your first try by using Wysebridge.com Patent Bar Review today.

Accelerate your success today

Experience unparalleled success with Wysebridge Patent Bar Review’s Prep Course: efficient, effective preparation for top results at unbeatable value—your gateway to passing the USPTO Patent Bar Exam.

6000+

Satisfied Users

We’ve served clients just graduating from college, to starting law school, and seasoned executives at fortune 50 companies.

81% vs 47%

Passing Rate

This is the Wysebridge Passing Rate for first time Patent Bar exam takers compared to the USPTO national average 47% passing rate.

87 hours

Studying Time

On average our users study for 87 hours before taking and passing the USPTO Patent Bar Exam.

How do we do it?

Wysebridge.com streamlines your study experience by eliminating unnecessary lectures and extraneous legal accreditation/CE content. We focus on deep data analytics to curate content and study materials that target the most tested topics and frequently asked questions on the USPTO Patent Bar.

%

Case Example: Expert Insights + Data Driven Content

Most Patent Bar Exam questions (77%) are drawn from just 5 of the 29 chapters.

The other 24 chapters statistically contribute only 23% of the questions.

Notably, the 10 most tested chapters account for 91% of the exam.

Focusing equally on all chapters leads to inefficient use of time and energy.

OUR SERVICES

Complete solution to pass the patent bar exam

Detailed Chapter Reviews

Quickly learn the architecture of the MPEP with our targeted and detailed MPEP chapter summaries, focusing on what really matters.

Frequency Charts

We make studying and focusing easy. By analyzing past exams and anecdotal evidence, we focus on what is tested most.

Hands-on Support

Get in touch with our Customer Support
anytime or drop into our discord and get all your questions resolved.

Practice Questions and Exams

With one of the largest post-AIA question databases (built from USPTO training resources), we have plenty of questions to practice on.

Flashcards

Over 1000 flashcards designed to help you rapidly assimilate key facts and knowledge about the exam.

Exam Insights and Tips

Gain invaluable insights, from prometric software bugs to practical tips about how to actually take the exam, on the day of your exam.

PATENT Bar Review Platform

Your personalized patent bar review program

Fully automate your studies

Never go without your studying platform. All content and access is available natively as an app on your phone or tablet!

Track your progress

Get an instant sense of how well you are progressing by looking at your scores and reports from studying!

Study and practice on demand

Never lose track of where you are in your studies. Simply pick up where you left off and continue no matter where you are in a course!

Studying

You are in solid hands

Utilizing Wysebridge.com is easy. Enroll for free today, and start your journey to becoming a Patent Attorney or Agent.

Enroll for free

Sign-up to Wysebridge.com for free and access all the content for full trial.

Start Studying

Familiarize yourself with our methodology and system, and start your learning immediately.

Crush the Patent Bar

Continue your studies using Wysebridge and pass the Patent Bar in less time for less money.

Trusted by 6,000+ happy Wysebridge.com users

The Wysebridge Patent Bar Review materials were very helpful in my patent bar preparation. Because some of the material was known to be repeated on the Exams, I was able to focus more time on those while also studying the other materials and test questions. I studied for two months (while working full time at a law firm) and I passed the first time. I credit passing the first time to Wysebridge and focusing on the provided exam questions and materials.

Kathleen Cafee

Bill & Melinda Gates Agricultural Innovations

get started

Pass the patent bar and become a leading patent practitioner today!

Continuous updates to content

We continue to refine and update our study materials and questions to ensure you are studying exactly what is needed to pass the patent bar exam.

Your personalized Patent Bar Review

Your platform enables you to study at your own pace with real-time data feedback, community support, and more.

Save up to 50% time and money

Time is money. So is not passing the patent bar on the first try. That’s why we built the best system to help you pass as efficiently as posssible.

Expertise and Data Insights

Our patent bar review team has served more than 6000+ individuals pass the patent bar exam. We built Wysebridge.com to help you accelerate your patent and IP law career.