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',
],
];
}
}