I have a CPT that gets its data by reading from an external server. The external server is the master of the data and my plugin stores a replication without an ability to update the master, therefor the ability to edit the content will just confuse the user, might even make him think that the master will be updated by the edits.
I basically wish to reuse the CPT admin framework but leave only the delete link (maybe not even that), even for administrators.
I can probably do it with CSS but looking for other options that feel less of a hack.
This is for esthetics of UI and not security, so I don’t care that it is possible to work around this.
I did something similar recently for a simple email log (for diagnosing some problems). I don’t have time to dissect the code, but hopefully it’ll be clear enough for you.
It creates a CPT for storing data that can be viewed in the admin (only), and allows the user to view and delete each post. NB: delete, not trash — no need for resurrection of deleted posts. Edit is changed to View, and metaboxes are replaced with a view template. This code is obviously missing the bits that write to the CPT and auto-purge old ones, but should be enough for your question.
/**
* custom post type for email log
*/
class LogEmailsPostTypeLog {
/**
* hooks
*/
public function __construct() {
add_action('admin_init', array($this, 'init'));
add_action('init', array($this, 'register'));
}
/**
* admin_init action
*/
public function init() {
global $typenow;
if (empty($typenow)) {
// try to pick it up from the query string
if (!empty($_GET['post'])) {
$post = get_post($_GET['post']);
$typenow = $post->post_type;
}
}
if ($typenow == 'log_emails_log') {
add_filter('display_post_states', '__return_false');
add_action('edit_form_after_title', array($this, 'adminEditAfterTitle'), 100);
add_filter('post_row_actions', array($this, 'adminPostRowActions'), 10, 2);
add_filter('bulk_actions-edit-log_emails_log', array($this, 'adminBulkActionsEdit'));
add_filter('manage_log_emails_log_posts_columns', array($this, 'adminManageColumns'));
add_action('manage_log_emails_log_posts_custom_column', array($this, 'adminManageCustomColumn'), 10, 2);
add_action('admin_print_footer_scripts', array($this, 'adminPrintFooterScripts'));
add_action('in_admin_header', array($this, 'adminScreenLayout'));
add_filter('views_edit-log_emails_log', array($this, 'adminViewsEdit'));
if (is_admin()) {
add_filter('gettext', array($this, 'adminGetText'), 10, 3);
}
wp_enqueue_script('jquery');
}
}
/**
* register Custom Post Type
*/
public function register() {
// register the post type
register_post_type('log_emails_log', array(
'labels' => array (
'name' => __('Email Logs', 'log-emails'),
'singular_name' => __('Email Log', 'log-emails'),
'add_new_item' => __('Add New Email Log', 'log-emails'),
'edit_item' => __('View Email Log', 'log-emails'),
'new_item' => __('New Email Log', 'log-emails'),
'view_item' => __('View Email Log', 'log-emails'),
'search_items' => __('Search Email Log', 'log-emails'),
'not_found' => __('No email logs found', 'log-emails'),
'not_found_in_trash' => __('No email logs found in Trash', 'log-emails'),
'parent_item_colon' => __('Parent email logs', 'log-emails'),
),
'description' => __('Email Logs, as a custom post type', 'log-emails'),
'exclude_from_search' => true,
'publicly_queryable' => false,
'public' => false,
'show_ui' => true,
'show_in_admin_bar' => false,
'menu_position' => 75,
'hierarchical' => false,
'has_archive' => false,
'supports' => array('nada'),
'rewrite' => false,
'can_export' => false,
'capabilities' => array (
'create_posts' => false,
'edit_post' => 'manage_options',
'read_post' => 'manage_options',
'delete_post' => 'manage_options',
'edit_posts' => 'manage_options',
'edit_others_posts' => 'manage_options',
'publish_posts' => 'manage_options',
'read_private_posts' => 'manage_options',
),
));
}
/**
* change some text on admin pages
* @param string $translation
* @param string $text
* @param string $domain
* @return string
*/
public function adminGetText($translation, $text, $domain) {
if ($domain == 'default') {
if ($text == 'Edit “%s”') {
$translation = 'View “%s”';
}
}
return $translation;
}
/**
* remove views we don't need from post list
* @param array $views
* @return array
*/
public function adminViewsEdit($views) {
unset($views['publish']);
unset($views['draft']);
return $views;
}
/**
* remove unwanted actions from post list
* @param array $actions
* @param WP_Post $post
* @return array
*/
public function adminPostRowActions($actions, $post) {
unset($actions['inline hide-if-no-js']); // "quick edit"
unset($actions['trash']);
unset($actions['edit']);
if ($post && $post->ID) {
// add View link
$actions['view'] = sprintf('<a href="https://wordpress.stackexchange.com/questions/124868/%s" title="https://wordpress.stackexchange.com/questions/124868/%s">%s</a>',
get_edit_post_link($post->ID),
__('View', 'log-emails'), __('View', 'log-emails'));
// add Delete link
$actions['delete'] = sprintf('<a href="https://wordpress.stackexchange.com/questions/124868/%s" title="https://wordpress.stackexchange.com/questions/124868/%s" class="submitdelete">%s</a>',
get_delete_post_link($post->ID, '', true),
__('Delete', 'log-emails'), __('Delete', 'log-emails'));
}
return $actions;
}
/**
* change the list of available bulk actions
* @param array $actions
* @return array
*/
public function adminBulkActionsEdit($actions) {
unset($actions['edit']);
return $actions;
}
/**
* filter to add columns to post list
* @param array $posts_columns
* @return array
*/
public function adminManageColumns($posts_columns) {
$posts_columns['title'] = 'Subject';
$posts_columns['_log_emails_log_to'] = 'Recipients';
return $posts_columns;
}
/**
* action to add custom columns to post list
* @param string $column_name
* @param int $post_id
*/
public function adminManageCustomColumn($column_name, $post_id) {
switch ($column_name) {
case '_log_emails_log_to':
$post = get_post($post_id);
if ($post) {
echo htmlspecialchars(get_post_meta($post_id, '_log_emails_log_to', true));
}
break;
}
}
/**
* change the screen layout
*/
public function adminScreenLayout() {
// set max / default layout as single column
add_screen_option('layout_columns', array('max' => 1, 'default' => 1));
}
/**
* drop all the metaboxes and output what we want to show
*/
public function adminEditAfterTitle($post) {
global $wp_meta_boxes;
// remove all meta boxes
$wp_meta_boxes = array('log_emails_log' => array(
'advanced' => array(),
'side' => array(),
'normal' => array(),
));
// show my admin form
require LOG_EMAILS_PLUGIN_ROOT . 'views/log-detail.php';
}
/**
* replace Trash bulk actions with Delete
* NB: WP admin already handles the delete action, it just doesn't expose it as a bulk action
*/
public function adminPrintFooterScripts() {
?>
<script>
jQuery("select[name="action"],select[name="action2"]").find("option[value="trash"]").each(function() {
this.value="delete";
jQuery(this).text("<?php esc_attr_e('Delete', 'log-emails'); ?>");
});
</script>
<?php
}
}