migrate_legacy_content_modules(); if ( Module_Registry::is_enabled( 'auto_add_anchor' ) ) { add_filter( 'block_editor_settings_all', [ $this, 'enable_anchor_target' ] ); } if ( Module_Registry::is_enabled( 'disable_comments' ) ) { add_action( 'init', [ $this, 'disable_comments_post_type_support' ], 100 ); add_action( 'admin_menu', [ $this, 'remove_comments_admin_menu' ], 100 ); add_action( 'wp_dashboard_setup', [ $this, 'remove_comments_dashboard_widget' ], 100 ); add_action( 'admin_bar_menu', [ $this, 'remove_comments_admin_bar_item' ], 100 ); add_filter( 'comments_open', '__return_false', 20 ); add_filter( 'pings_open', '__return_false', 20 ); add_filter( 'comments_array', '__return_empty_array', 20 ); add_filter( 'wp_insert_post_data', [ $this, 'close_comments_and_pings' ], 20 ); } if ( ! Module_Registry::is_enabled( 'publish_missed_schedule' ) ) { add_action( 'init', [ $this, 'maybe_remove_publication_check_schedule' ], 20 ); } add_filter( 'adminoptim_notification_message_' . self::SECTION_ID, static function ( string $message, string $display ): string { if ( 'banner' === $display ) { return $message; } if ( ! Module_Registry::is_pro_active() ) { return sprintf( /* translators: 1: Opening strong tag, 2: Closing strong tag. */ __( '%1$sUnlock advanced content tools.%2$s Get more publishing controls, content automation, and productivity features with Pro.', 'admin-optimizer' ), '', '' ); } return $message; }, 10, 2 ); add_filter( 'adminoptim_notification_banner_content_' . self::SECTION_ID, static function (): array { $content = [ [ 'message' => sprintf( /* translators: 1: Opening strong tag, 2: Closing strong tag. */ __( '%1$sFaster content workflows, better publishing control, fewer repetitive editing tasks.%2$s Leave a ★★★★★ review on WordPress.org and help others manage WordPress content more efficiently', 'admin-optimizer' ), '', '' ), 'cta_type' => 'review', ], [ 'message' => sprintf( /* translators: 1: Opening strong tag, 2: Closing strong tag. */ __( '%1$sHaving issues with Admin Optimizer content tools?%2$s', 'admin-optimizer' ), '', '', ), 'cta_type' => 'support', ], ]; return $content[ wp_rand( 0, 1 ) ]; }, ); } /** * Move the retired Post Cloner and Content Refresh state into Content Refresher. * * Removing the legacy toggle keys makes this migration self-marking and * one-time, matching the other Section-level legacy migrations. * Existing Content Refresher settings and activation state are never * overwritten. * * @return void */ private function migrate_legacy_content_modules(): void { $module_options = get_option( MODULES_OPTION, [] ); $module_options = is_array( $module_options ) ? $module_options : []; $has_clone_toggle = array_key_exists( 'enable_post_cloner', $module_options ); $has_refresh_toggle = array_key_exists( 'enable_post_republisher', $module_options ); if ( ! $has_clone_toggle && ! $has_refresh_toggle ) { return; } $clone_enabled = $has_clone_toggle && Module_Registry::is_enabled( 'post_cloner' ); $refresh_enabled = $has_refresh_toggle && Module_Registry::is_enabled( 'content_refresh' ); $new_option_name = Module_Registry::get_option_name( 'content_refresher' ); if ( null === $new_option_name ) { return; } $current_options = get_option( $new_option_name, null ); if ( null === $current_options ) { $clone_options = get_option( 'adminoptim_post_cloner', [] ); $clone_options = is_array( $clone_options ) ? $clone_options : []; $refresh_options = get_option( 'adminoptim_post_republisher', [] ); $refresh_options = is_array( $refresh_options ) ? $refresh_options : []; $migrated_options = [ 'allow_cloning' => $clone_enabled ? 1 : 0, 'clone_post_types' => isset( $clone_options['post_types'] ) ? (array) $clone_options['post_types'] : [ 'post', 'page' ], 'clone_roles' => isset( $clone_options['clone_roles'] ) ? (array) $clone_options['clone_roles'] : [ 'administrator' ], 'after_cloning' => isset( $clone_options['after_cloning'] ) && 'edit' === $clone_options['after_cloning'] ? 'edit' : 'return', 'allow_content_refresh' => $refresh_enabled ? 1 : 0, 'refresh_post_types' => isset( $refresh_options['post_types'] ) ? (array) $refresh_options['post_types'] : [ 'post', 'page' ], 'refresh_roles' => isset( $refresh_options['republish_roles'] ) ? (array) $refresh_options['republish_roles'] : [ 'administrator' ], 'replace_author' => ! empty( $refresh_options['replace_author'] ) ? 1 : 0, 'replace_publish_date' => ! empty( $refresh_options['replace_publish_date'] ) ? 1 : 0, 'replace_modified_date' => ! empty( $refresh_options['replace_modified_date'] ) ? 1 : 0, 'replace_tax' => ! empty( $refresh_options['replace_tax'] ) ? 1 : 0, 'replace_post_metas' => ! empty( $refresh_options['replace_post_metas'] ) ? 1 : 0, 'update_guid' => ! empty( $refresh_options['update_guid'] ) ? 1 : 0, 'delete_comments' => ! empty( $refresh_options['delete_comments'] ) ? 1 : 0, 'after_republish_action' => isset( $refresh_options['after_republish_action'] ) && 'delete' === $refresh_options['after_republish_action'] ? 'delete' : 'trash', ]; if ( ! update_option( $new_option_name, $migrated_options ) ) { return; } } if ( ! array_key_exists( 'enable_content_refresher', $module_options ) ) { $module_options['enable_content_refresher'] = $clone_enabled || $refresh_enabled; } unset( $module_options['enable_post_cloner'], $module_options['enable_post_republisher'] ); update_option( MODULES_OPTION, $module_options ); } /** * Remove check missed post schedule * * @return void */ public function maybe_remove_publication_check_schedule() { if ( function_exists( 'as_has_scheduled_action' ) && as_has_scheduled_action( 'adminoptim_publish_missed_post' ) ) { as_unschedule_action( 'adminoptim_publish_missed_post' ); } } /** * Auto add anchor target to Headings block * * @param array $editor_settings Editor settings. * * @return array */ public function enable_anchor_target( $editor_settings ) { $editor_settings['generateAnchors'] = true; return $editor_settings; } /** * Remove comment and trackback support from every registered post type. * * @return void */ public function disable_comments_post_type_support() { foreach ( get_post_types() as $post_type ) { if ( post_type_supports( $post_type, 'comments' ) ) { remove_post_type_support( $post_type, 'comments' ); } if ( post_type_supports( $post_type, 'trackbacks' ) ) { remove_post_type_support( $post_type, 'trackbacks' ); } } } /** * Remove comment-related items from the admin menu. * * @return void */ public function remove_comments_admin_menu() { remove_menu_page( 'edit-comments.php' ); remove_submenu_page( 'options-general.php', 'options-discussion.php' ); } /** * Remove the Recent Comments dashboard widget. * * @return void */ public function remove_comments_dashboard_widget() { remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' ); } /** * Remove the Comments item from the admin toolbar. * * @param \WP_Admin_Bar $wp_admin_bar Admin toolbar instance. * * @return void */ public function remove_comments_admin_bar_item( $wp_admin_bar ) { $wp_admin_bar->remove_node( 'comments' ); } /** * Keep comments and pings closed when content is created or updated. * * @param array $data Slashed post data to be inserted. * * @return array */ public function close_comments_and_pings( $data ) { $data['comment_status'] = 'closed'; $data['ping_status'] = 'closed'; return $data; } /** * Ordinary module IDs this Section owns, mapped to their navigation labels. * * @return array */ protected function section_nav_modules(): array { return [ 'content_refresher' => 'Content Refresher', 'modified_date' => 'Lock Post Modified Date', 'disable_gutenberg_editor' => 'Content Editor', 'content_author_policy' => 'Content Author Policy', ]; } /** * Section-owned "Content Controls" presentation group of lightweight * SECTION_FEATURE capabilities. * * @return array{label:string,description:string,members:array} */ protected function section_feature_group(): ?array { return [ 'label' => __( 'Content Controls', 'admin-optimizer' ), 'description' => __( 'Manage publishing, editing, and content behavior across WordPress.', 'admin-optimizer' ), 'members' => [ 'publish_missed_schedule', 'disable_comments', 'auto_add_anchor', 'page_ordering', ], ]; } }