1
Please review this mu-plugin which adds the feature I would like to see added on, I think SEO should be opt-in for custom post types
<?php
/**
* Plugin Name: SmartCrawl CPT Settings
* Description: Control which post types SmartCrawl Pro is enabled for.
* Version: 1.0
* Author: Terrance Orletsky - Earthman Media
* Author URI: https://earthmanmedia.com
* License: MIT
*/
/**
* Get allowed post types for SmartCrawl. Defaults to post and page if not set.
*
* @return array Associative array of post_type => 1.
*/
function smartcrawl_cpt_get_allowed() {
$saved = get_option( 'smartcrawl_allowed_post_types' );
if ( false === $saved ) {
return array(
'post' => 1,
'page' => 1,
);
}
return (array) $saved;
}
/**
* Bootstrap all hooks after plugins are loaded so all CPTs are registered.
*/
function smartcrawl_cpt_init() {
add_action( 'admin_menu', 'smartcrawl_cpt_admin_menu' );
add_action( 'admin_init', 'smartcrawl_cpt_register_settings' );
add_action( 'add_meta_boxes', 'smartcrawl_cpt_remove_metabox', 99 );
add_filter( 'wds_get_post_types_for_overview', 'smartcrawl_cpt_filter_overview_types' );
add_action( 'admin_init', 'smartcrawl_cpt_remove_columns', 99 );
add_filter( 'post_row_actions', 'smartcrawl_cpt_filter_row_actions', 9, 2 );
add_filter( 'page_row_actions', 'smartcrawl_cpt_filter_row_actions', 9, 2 );
}
add_action( 'plugins_loaded', 'smartcrawl_cpt_init' );
/**
* Register the settings page under SmartCrawl menu.
*/
function smartcrawl_cpt_admin_menu() {
add_submenu_page(
'wds_wizard',
'Post Types Enabled',
'Post Types Enabled',
'manage_options',
'smartcrawl-cpt-settings',
'smartcrawl_cpt_render_page'
);
}
/**
* Register the setting.
*/
function smartcrawl_cpt_register_settings() {
register_setting( 'smartcrawl_cpt_settings', 'smartcrawl_allowed_post_types' );
}
/**
* Render the settings page.
*/
function smartcrawl_cpt_render_page() {
$allowed = smartcrawl_cpt_get_allowed();
$post_types = get_post_types( array( 'show_ui' => true ), 'objects' );
?>
<div class="wrap">
<h1>Post Types Enabled</h1>
Select which post types SmartCrawl Pro should be active on.
<form method="post" action="options.php">
<?php settings_fields( 'smartcrawl_cpt_settings' ); ?>
<table class="form-table">
<tr>
<th scope="row">Enabled Post Types</th>
<td>
<fieldset>
<?php foreach ( $post_types as $pt ) : ?>
<label>
<input
type="checkbox"
name="smartcrawl_allowed_post_types[<?php echo esc_attr( $pt->name ); ?>]"
value="1"
<?php checked( ! empty( $allowed[ $pt->name ] ) ); ?>
/>
<?php echo esc_html( $pt->labels->name ); ?>
(<?php echo esc_html( $pt->name ); ?>)
</label>
<?php endforeach; ?>
</fieldset>
<p class="description">Unchecked types will have SmartCrawl metabox, SEO columns, and analysis disabled.
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
/**
* Remove SmartCrawl metabox from disallowed post types.
*/
function smartcrawl_cpt_remove_metabox() {
$allowed = smartcrawl_cpt_get_allowed();
$screen = get_current_screen();
if ( ! $screen || empty( $screen->post_type ) ) {
return;
}
if ( empty( $allowed[ $screen->post_type ] ) ) {
remove_meta_box( 'wds-wds-meta-box', $screen->post_type, 'normal' );
remove_meta_box( 'wds_seomoz_urlmetrics', $screen->post_type, 'normal' );
}
}
/**
* Filter SmartCrawl's post types for SEO overview/analysis.
*
* @param array $post_types Post types used in SEO overview.
* @return array Filtered post types.
*/
function smartcrawl_cpt_filter_overview_types( $post_types ) {
$allowed = smartcrawl_cpt_get_allowed();
return array_filter(
$post_types,
function ( $type ) use ( $allowed ) {
return ! empty( $allowed[ $type ] );
}
);
}
/**
* Remove SmartCrawl SEO columns and row actions from disallowed post types.
*
* SmartCrawl hooks columns/row-actions via an instance method, so we must
* find the actual object instance from $wp_filter to unhook it.
*/
function smartcrawl_cpt_remove_columns() {
global $wp_filter;
$allowed = smartcrawl_cpt_get_allowed();
$post_types = get_post_types( array( 'show_ui' => true ) );
// Find the SmartCrawl Metabox instance from its known hook.
$instance = null;
if ( isset( $wp_filter['post_row_actions'] ) ) {
foreach ( $wp_filter['post_row_actions']->callbacks as $priority => $hooks ) {
foreach ( $hooks as $hook ) {
if (
is_array( $hook['function'] )
&& is_object( $hook['function'][0] )
&& $hook['function'][0] instanceof \SmartCrawl\Admin\Metabox
) {
$instance = $hook['function'][0];
break 2;
}
}
}
}
if ( ! $instance ) {
return;
}
foreach ( $post_types as $type ) {
if ( empty( $allowed[ $type ] ) ) {
remove_filter( "manage_{$type}_posts_columns", array( $instance, 'smartcrawl_meta_column_heading' ), 20 );
remove_action( "manage_{$type}_posts_custom_column", array( $instance, 'smartcrawl_meta_column_content' ), 20 );
}
}
}
/**
* Suppress SmartCrawl meta-details output in row actions for disallowed types.
*
* SmartCrawl's post_row_actions hook echoes HTML directly (not appended to $actions),
* so we use output buffering before it runs (priority 9 < SmartCrawl's 10) to capture
* and discard the output for disallowed post types.
*
* @param string[] $actions Row action links.
* @param \WP_Post $post The post object.
* @return string[] Unmodified actions.
*/
function smartcrawl_cpt_filter_row_actions( $actions, $post ) {
$allowed = smartcrawl_cpt_get_allowed();
if ( empty( $allowed[ $post->post_type ] ) ) {
// Start buffering to capture SmartCrawl's echoed output at priority 10.
ob_start();
// Schedule cleanup at priority 11 (right after SmartCrawl's priority 10).
add_filter(
current_filter(),
function ( $a ) {
ob_end_clean();
return $a;
},
11,
1
);
}
return $actions;
}