create a mostly read only CPT

时间:2013-11-29 作者:Mark Kaplun

我有一个CPT,它通过从外部服务器读取数据来获取数据。外部服务器是数据的主服务器,而我的插件存储了一个复制,但没有更新主服务器的能力,因此编辑内容的能力只会让用户感到困惑,甚至可能让他认为主服务器会通过编辑来更新。

我基本上希望重用CPT管理框架,但只保留删除链接(甚至可能没有),即使对于管理员也是如此。

我可能可以用CSS来做,但我正在寻找其他感觉不太像黑客的选项。

这是为了UI的美学,而不是安全性,所以我不在乎是否有可能解决这个问题。

2 个回复
最合适的回答,由SO网友:webaware 整理而成

最近,我为一个简单的电子邮件日志做了类似的事情(用于诊断一些问题)。我没有时间剖析代码,但希望它对您来说足够清楚。

它创建了一个CPT,用于存储可在管理员(仅限)中查看的数据,并允许用户查看和删除每篇帖子。注意:删除,而不是垃圾——不需要恢复被删除的帖子。将“编辑”更改为“视图”,并用视图样板替换元框。这段代码显然缺少写入CPT的位和自动清除旧位的位,但应该足以回答您的问题。

/**
* 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="%s" title="%s">%s</a>\',
                get_edit_post_link($post->ID),
                __(\'View\', \'log-emails\'), __(\'View\', \'log-emails\'));

            // add Delete link
            $actions[\'delete\'] = sprintf(\'<a href="%s" title="%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
    }

}

SO网友:s_ha_dum

可以用只读元框替换编辑器。

// use the action to create a place for your meta box
function add_before_editor($post) {
  if (\'post\' == $post->post_type) {
    remove_post_type_support(\'post\',\'editor\');
    do_meta_boxes(\'post\', \'read_only_content\', $post);
  }
}
add_action(\'edit_form_after_title\',\'add_before_editor\');

// add a box the location just created
function read_only_content_box() {
  add_meta_box(
    \'read_only_content_box\', // id, used as the html id att
    __( \'Post Content (Read Only)\' ), // meta box title
    \'read_only_cb\', // callback function, spits out the content
    \'post\', // post type or page. This adds to posts only
    \'read_only_content\', // context, where on the screen
    \'low\' // priority, where should this go in the context
  );
}
function read_only_cb($post) {
  echo apply_filters(\'the_content\',$post->post_content);
}
add_action( \'add_meta_boxes\', \'read_only_content_box\' );
我假设您正在禁用此帖子类型的“保存”功能。如果不是--如果您需要一些部分来保存而不是主要内容--您可能需要连接到表单处理中,以防止有人对此进行黑客攻击。照目前的情况,帖子内容不会被覆盖,但绕过它并不难。

要完全删除编辑功能,请使用capability 参数何时you register your post type. 将该参数设置为read_post 整个类型变成“只读”。您还需要\'show_in_admin_bar\' => false,. 示例参数数组:

  $args = array(
    \'labels\'             => $labels,
    \'public\'             => true,
    \'publicly_queryable\' => true,
    \'show_ui\'            => true,
    \'show_in_menu\'       => true,
    \'query_var\'          => true,
    \'rewrite\'            => array( \'slug\' => \'book\' ),
    \'capability_type\'    => \'post\',
    \'capabilities\'       => array(\'read_post\'),
    \'show_in_admin_bar\'  => false,
    \'has_archive\'        => true,
    \'hierarchical\'       => false,
  );

结束

相关推荐