settings = $settings; $this->story_post_type = $story_post_type; } /** * Registers Filters and actions * * @since 1.13.0 */ public function register(): void { add_filter( 'pre_handle_404', [ $this, 'redirect_post_type_archive_urls' ], 10, 2 ); add_action( 'add_option_' . $this->settings::SETTING_NAME_ARCHIVE, [ $this, 'update_archive_setting' ] ); add_action( 'update_option_' . $this->settings::SETTING_NAME_ARCHIVE, [ $this, 'update_archive_setting' ] ); add_action( 'add_option_' . $this->settings::SETTING_NAME_ARCHIVE_PAGE_ID, [ $this, 'update_archive_setting' ] ); add_action( 'update_option_' . $this->settings::SETTING_NAME_ARCHIVE_PAGE_ID, [ $this, 'update_archive_setting' ] ); add_filter( 'display_post_states', [ $this, 'filter_display_post_states' ], 10, 2 ); add_action( 'pre_get_posts', [ $this, 'pre_get_posts' ] ); add_action( 'wp_trash_post', [ $this, 'on_remove_archive_page' ] ); add_action( 'delete_post', [ $this, 'on_remove_archive_page' ] ); } /** * Handles redirects to the post type archive. * * @since 1.13.0 * * @param bool|mixed $bypass Pass-through of the pre_handle_404 filter value. * @param \WP_Query $query The WP_Query object. * @return bool|mixed Whether to pass-through or not. */ public function redirect_post_type_archive_urls( $bypass, WP_Query $query ) { global $wp_rewrite; if ( $bypass || ! \is_string( $this->story_post_type->get_has_archive() ) || ( ! $wp_rewrite instanceof WP_Rewrite || ! $wp_rewrite->using_permalinks() ) ) { return $bypass; } // 'pagename' is for most permalink types, name is for when the %postname% is used as a top-level field. if ( $this->story_post_type::REWRITE_SLUG === $query->get( 'pagename' ) || $this->story_post_type::REWRITE_SLUG === $query->get( 'name' ) ) { $redirect_url = get_post_type_archive_link( $this->story_post_type->get_slug() ); if ( ! $redirect_url ) { return $bypass; } // Only exit if there was actually a location to redirect to. // Allows filtering location in tests to verify behavior. if ( wp_safe_redirect( $redirect_url, 301 ) ) { exit; } } return $bypass; } /** * Clear rewrite rules on update on setting. * * @since 1.13.0 */ public function update_archive_setting(): void { $this->story_post_type->unregister_post_type(); $this->story_post_type->register_post_type(); if ( ! \defined( '\WPCOM_IS_VIP_ENV' ) || false === \WPCOM_IS_VIP_ENV ) { flush_rewrite_rules( false ); } } /** * Modifies the current query to set up the custom archive page. * * @since 1.13.0 * * @param WP_Query $query Current query instance, passed by reference. */ public function pre_get_posts( WP_Query $query ): void { if ( ! \is_string( $this->story_post_type->get_has_archive() ) ) { return; } if ( $query->is_admin || ! $query->is_main_query() ) { return; } if ( ! $query->is_post_type_archive( $this->story_post_type->get_slug() ) ) { return; } $custom_archive_page_id = (int) $this->settings->get_setting( $this->settings::SETTING_NAME_ARCHIVE_PAGE_ID ); $query->set( 'page_id', $custom_archive_page_id ); $query->set( 'post_type', 'page' ); $query->is_post_type_archive = false; $query->is_archive = false; $query->is_singular = true; $query->is_page = true; } /** * Resets archive settings when the custom archive page is trashed. * * @since 1.14.0 * * @param int $postid Post ID. */ public function on_remove_archive_page( int $postid ): void { if ( 'page' !== get_post_type( $postid ) ) { return; } $custom_archive_page_id = (int) $this->settings->get_setting( $this->settings::SETTING_NAME_ARCHIVE_PAGE_ID ); if ( $custom_archive_page_id !== $postid ) { return; } $this->settings->update_setting( $this->settings::SETTING_NAME_ARCHIVE, 'default' ); $this->settings->update_setting( $this->settings::SETTING_NAME_ARCHIVE_PAGE_ID, 0 ); } /** * Filters the default post display states used in the posts list table. * * @since 1.13.0 * * @param string[]|mixed $post_states An array of post display states. * @param WP_Post|null $post The current post object. * @return string[]|mixed Filtered post display states. * * @template T * * @phpstan-return ($post_states is array ? array : mixed) */ public function filter_display_post_states( $post_states, ?WP_Post $post ) { if ( ! \is_array( $post_states ) || ! $post ) { return $post_states; } if ( ! \is_string( $this->story_post_type->get_has_archive() ) ) { return $post_states; } $custom_archive_page_id = (int) $this->settings->get_setting( $this->settings::SETTING_NAME_ARCHIVE_PAGE_ID ); if ( $post->ID === $custom_archive_page_id ) { $post_states['web_stories_archive_page'] = __( 'Web Stories Archive Page', 'web-stories' ); } return $post_states; } }