repository = new Feed_Repository(); $this->builder = new Feed_Builder(); $this->access = new Access_Policy( $this->repository ); $this->controller = new Feed_Controller( $this->repository, $this->builder, $this->access ); } /** * Registers hooks. */ public function boot(): void { add_action( 'init', array( $this->repository, 'register_post_type' ) ); add_action( 'init', array( Endpoint::class, 'add_rewrite_rule' ) ); ( new Endpoint( $this->controller ) )->register(); // Cache invalidation: one cheap option write bumps a generation number. add_action( 'wp_after_insert_post', array( $this, 'on_after_insert_post' ), 10, 2 ); add_action( 'transition_post_status', array( $this, 'on_status_transition' ), 10, 3 ); add_action( 'deleted_post', array( $this, 'on_deleted_post' ), 10, 2 ); add_action( 'added_post_meta', array( $this, 'on_meta_change' ), 10, 4 ); add_action( 'updated_post_meta', array( $this, 'on_meta_change' ), 10, 4 ); add_action( 'deleted_post_meta', array( $this, 'on_meta_change' ), 10, 4 ); add_action( 'set_object_terms', array( $this, 'on_terms_set' ), 10, 1 ); add_action( 'deleted_term_relationships', array( $this, 'on_terms_set' ), 10, 1 ); add_action( 'edited_term', array( Feed_Builder::class, 'bump_generation' ) ); add_action( 'delete_term', array( Feed_Builder::class, 'bump_generation' ) ); add_action( 'profile_update', array( Feed_Builder::class, 'bump_generation' ) ); if ( is_admin() ) { ( new Admin( $this->repository, $this->builder ) )->register(); } } /** * Whether a post could appear in a public feed (revisions, autosaves, * FeedWeaver's own records and non-viewable types never do). * * @param \WP_Post|null $post Post. * @return bool */ private function is_feed_relevant( $post ): bool { return $post instanceof \WP_Post && Feed_Repository::POST_TYPE !== $post->post_type && 'revision' !== $post->post_type && is_post_type_viewable( $post->post_type ); } /** * After a post (with its terms and meta) has been saved: refresh when it is published. * * @param int $post_id Post ID. * @param \WP_Post $post Post. */ public function on_after_insert_post( $post_id, $post ): void { if ( $this->is_feed_relevant( $post ) && 'publish' === $post->post_status && ! wp_is_post_autosave( $post_id ) ) { Feed_Builder::bump_generation(); } } /** * Publishing, unpublishing, trashing: any change to or from "publish". * * @param string $new_status New status. * @param string $old_status Old status. * @param \WP_Post $post Post. */ public function on_status_transition( $new_status, $old_status, $post ): void { if ( $new_status !== $old_status && ( 'publish' === $new_status || 'publish' === $old_status ) && $this->is_feed_relevant( $post ) ) { Feed_Builder::bump_generation(); } } /** * Permanent deletion of a published post. * * @param int $post_id Post ID. * @param \WP_Post|null $post Post (WordPress 5.5+). */ public function on_deleted_post( $post_id, $post = null ): void { if ( $this->is_feed_relevant( $post ) && 'publish' === $post->post_status ) { Feed_Builder::bump_generation(); } } /** * Term assignments changed (REST, bulk edit, code): refresh when the post is published. * * @param int $object_id Post ID. */ public function on_terms_set( $object_id ): void { $post = get_post( (int) $object_id ); if ( $this->is_feed_relevant( $post ) && 'publish' === $post->post_status ) { Feed_Builder::bump_generation(); } } /** * Public custom field changes on published posts (protected "_" keys never appear in feeds). * * @param int|int[] $meta_id Meta ID(s). * @param int $post_id Post ID. * @param string $meta_key Meta key. */ public function on_meta_change( $meta_id, $post_id, $meta_key ): void { if ( is_string( $meta_key ) && '' !== $meta_key && '_' !== $meta_key[0] && 'publish' === get_post_status( $post_id ) ) { Feed_Builder::bump_generation(); } } /** * Activation: register the rules, then flush once. */ public static function activate(): void { ( new Feed_Repository() )->register_post_type(); Endpoint::add_rewrite_rule(); flush_rewrite_rules( false ); update_option( Endpoint::VERSION_OPTION, Endpoint::REWRITE_VERSION, true ); } /** * Deactivation: remove the rules. */ public static function deactivate(): void { flush_rewrite_rules( false ); } }