관리-도구
편집 파일: SlugMonitor.php
<?php namespace AIOSEO\Plugin\Common\Admin; // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Monitors changes to post slugs. * * @since 4.2.3 */ class SlugMonitor { /** * Holds posts that have been updated. * * @since 4.2.3 * * @var array */ private $updatedPosts = []; /** * Class constructor. * * @since 4.2.3 */ public function __construct() { // We can't monitor changes without permalinks enabled. if ( ! get_option( 'permalink_structure' ) ) { return; } add_action( 'pre_post_update', [ $this, 'prePostUpdate' ] ); // WP 5.6+. if ( function_exists( 'wp_after_insert_post' ) ) { add_action( 'wp_after_insert_post', [ $this, 'afterInsertPost' ], 11, 4 ); } else { add_action( 'post_updated', [ $this, 'postUpdated' ], 11, 3 ); } } /** * Remember the previous post permalink. * * @since 4.2.3 * * @param integer $postId The post ID. * @return void */ public function prePostUpdate( $postId ) { $this->updatedPosts[ $postId ] = get_permalink( $postId ); } /** * Called when a post has been completely inserted ( with categories and meta ). * * @since 4.2.3 * * @param integer $postId The post ID. * @param \WP_Post $post The post object. * @param bool $update Whether this is an existing post being updated. * @param null|\WP_Post $postBefore The post object before changes were made. * @return void */ public function afterInsertPost( $postId, $post = null, $update = false, $postBefore = null ) { if ( ! $update ) { return; } $this->postUpdated( $postId, $post, $postBefore ); } /** * Called when a post has been updated - check if the slug has changed. * * @since 4.2.3 * * @param integer $postId The post ID. * @param \WP_Post $post The post object. * @param \WP_Post $postBefore The post object before changes were made. * @return void */ public function postUpdated( $postId, $post = null, $postBefore = null ) { if ( ! isset( $this->updatedPosts[ $postId ] ) ) { return; } $before = aioseo()->helpers->getPermalinkPath( $this->updatedPosts[ $postId ] ); $after = aioseo()->helpers->getPermalinkPath( get_permalink( $postId ) ); if ( ! aioseo()->helpers->hasPermalinkChanged( $before, $after ) ) { return; } // Can we monitor this slug? if ( ! $this->canMonitorPost( $post, $postBefore ) ) { return; } // Ask aioseo-redirects if automatic redirects is monitoring it. if ( $this->automaticRedirect( $post->post_type, $before, $after ) ) { return; } // Filter to allow users to disable the slug monitor messages. if ( apply_filters( 'aioseo_redirects_disable_slug_monitor', false ) ) { return; } $redirectUrl = $this->manualRedirectUrl( [ 'url' => $before, 'target' => $after, 'type' => 301 ] ); $message = __( 'The permalink for this post just changed! This could result in 404 errors for your site visitors.', 'all-in-one-seo-pack' ); // Default notice redirecting to the Redirects screen. $action = [ 'url' => $redirectUrl, 'label' => __( 'Add Redirect to improve SEO', 'all-in-one-seo-pack' ), 'target' => '_blank', 'class' => 'aioseo-redirects-slug-changed' ]; // If redirects is active we'll show add-redirect in a modal. if ( aioseo()->addons->getLoadedAddon( 'redirects' ) ) { // We need to remove the target here so the action keeps the url used by the add-redirect modal. unset( $action['target'] ); } aioseo()->wpNotices->addNotice( $message, 'warning', [ 'actions' => [ $action ] ], [ 'posts' ] ); } /** * Checks if this is a post we can monitor. * * @since 4.2.3 * * @param \WP_Post $post The post object. * @param \WP_Post $postBefore The post object before changes were made. * @return boolean True if we can monitor this post. */ private function canMonitorPost( $post, $postBefore ) { // Check that this is for the expected post. if ( ! isset( $post->ID ) || ! isset( $this->updatedPosts[ $post->ID ] ) ) { return false; } // Don't do anything if we're not published. if ( 'publish' !== $post->post_status || 'publish' !== $postBefore->post_status ) { return false; } // Don't do anything is the post type is not public. if ( ! is_post_type_viewable( $post->post_type ) ) { return false; } return true; } /** * Tries to add a automatic redirect. * * @since 4.2.3 * * @param string $postType The post type. * @param string $before The url before. * @param string $after The url after. * @return bool True if an automatic redirect was added. */ private function automaticRedirect( $postType, $before, $after ) { if ( ! aioseo()->addons->getLoadedAddon( 'redirects' ) ) { return false; } return aioseoRedirects()->monitor->automaticRedirect( $postType, $before, $after ); } /** * Generates a URL for adding manual redirects. * * @since 4.2.3 * * @param array $urls An array of [url, target, type, slash, case, regex]. * @return string The redirect link. */ public function manualRedirectUrl( $urls ) { if ( ! aioseo()->addons->getLoadedAddon( 'redirects' ) ) { return admin_url( 'admin.php?page=aioseo-redirects' ); } return aioseoRedirects()->helpers->manualRedirectUrl( $urls ); } }