是否将下拉列表添加到备注表单?

时间:2013-06-02 作者:Daniel Foltynek

有人能帮我在Wordpress评论表单中创建一个下拉菜单或(单选按钮),以便新用户可以选择他们的用户角色(例如教师+学生)?

下拉列表或单选按钮的输出将出现在注释区域的某处

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

过滤器comment_form_field_comment 添加select 带有label. comment_post 保存值

  • 过滤器comment_text 显示注释的值
  • 示例代码:

    add_filter( \'comment_form_field_comment\', function( $field ) {
    
        global $wp_roles;
    
        $user = wp_get_current_user();
    
        $select = \'<p><label for="roleselect">Your role:</label>
        <select name="prefix_role" id="roleselect">
        <option value="">Select a role</option>\';
    
        foreach ( $wp_roles->roles as $key => $role )
            $select .= sprintf(
                \'<option value="%1$s" %2$s>%3$s</option>\',
                esc_attr( $key ),
                ( in_array( $key, $user->roles) ? \'selected\' : \'\' ),
                esc_html( $role[\'name\'] )
            );
    
        $select .= \'</select></p>\';
    
        return $select . $field;
    });
    
    add_action( \'comment_post\', function( $comment_ID ) {
    
        $roles = new WP_Roles;
        $role_keys = array_keys( $roles->roles );
    
        if ( isset ( $_POST[\'prefix_role\'] ) and in_array( $_POST[\'prefix_role\'], $role_keys ) )
            update_comment_meta( $comment_ID, \'prefix_role\', $_POST[\'prefix_role\'] );
    });
    
    add_filter( \'comment_text\', function( $text, $comment ) {
    
        if ( $role = get_comment_meta( $comment->comment_ID, \'prefix_role\', TRUE ) )
            $text = "Role: $role<br> $text";
    
        return $text;
    }, 10, 2 );
    
    更新我已经重写了代码以使用真正的MVC模式。解释如下。

    插件标题

    <?php # -*- coding: utf-8 -*-
    namespace WPSE;
    /**
     * Plugin Name: Comment Meta Demo
     * Description: Create, save and display a comment meta field. Here, a commentator can select a role.
     * Plugin URI:  http://wordpress.stackexchange.com/q/101579/73
     * Version:     2013.06.06
     * Author:      Fuxia Scholz
     * Licence:     MIT
     * License URI: http://opensource.org/licenses/MIT
     */
    
    \\add_action(
        \'wp_loaded\',
        array( __NAMESPACE__ . \'\\Comment_Meta_Controller\', \'init\' )
    );
    
    控制器
    /**
     * Controller
     *
     * Assigns Views and models to actions and filters
     */
    class Comment_Meta_Controller
    {
        /**
         * Callback for add_action(). Creates a new instance.
         *
         * @wp-hook login_init
         */
        public function init()
        {
            return new self;
        }
    
        /**
         * Set up objects, register footer action callback.
         *
         * @wp-hook login_init
         */
        protected function __construct()
        {
    
            $data   = new Comment_Meta_Builtin_Roles( \'_comment_role\' );
            // Use this for custom roles instead
            //$data   = new Comment_Meta_Custom_Roles( \'_comment_role\' );
            $input  = new Comment_Meta_Role_Selector( $data );
            $output = new Comment_Meta_Role_Display( $data );
    
            // remove this if you want to show the select field with
            // do_action( \'comment_role_selector\' );
            \\add_filter( \'comment_form_field_comment\', array ( $input, \'show\' ), 10, 2 );
    
            \\add_action( \'comment_role_selector\', array ( $input, \'print_select\' ) );
    
            // remove this if you want to show the select field with
            // do_action( \'comment_role_selector\' );
            \\add_filter( \'comment_text\', array ( $output, \'show\' ), 10, 2 );
    
            \\add_action( \'comment_role_value\', array ( $output, \'show_action\' ), 10, 2 );
    
            if ( \'POST\' === $_SERVER[ \'REQUEST_METHOD\' ] )
                \\add_action( \'comment_post\', array ( $data, \'save\' ) );
        }
    }
    
    抽象元数据基类
    /**
     * Base class for handling comment meta data.
     */
    abstract class Comment_Meta_Data_Model
    {
        /**
         * Meta key
         *
         * @type string
         */
        protected $key;
    
        /**
         * Constructor
         *
         * @param string $key
         */
        public function __construct( $key )
        {
            $this->key = $key;
        }
    
        /**
         * Get current key
         *
         * @return string
         */
        public function get_key()
        {
            return $this->key;
        }
    
        /**
         * Wrapper for the native get_comment_meta()
         *
         * @param  int    $comment_ID
         * @return string
         */
        public function get_comment_meta( $comment_ID )
        {
            $meta    = \\get_comment_meta( $comment_ID, $this->key, TRUE );
            $allowed = $this->get_allowed_values();
    
            // get real display value
            if ( isset ( $allowed[ $meta ] ) )
                return $allowed[ $meta ];
    
            return \'\';
        }
    
        /**
         * Save comment mate data.
         *
         * @param  int  $comment_ID
         * @return bool
         */
        public function save( $comment_ID )
        {
            $role_keys = array_keys( $this->get_allowed_values() );
    
            if ( ! isset ( $_POST[ $this->key ] ) )
                return;
    
            if ( ! in_array( $_POST[ $this->key ], $role_keys ) )
                return;
    
            return \\update_comment_meta( $comment_ID, $this->key, $_POST[ $this->key ] );
        }
    
        /**
         * Get user role.
         */
        public function get_current_value()
        {
            $user = \\wp_get_current_user();
    
            if ( empty ( $user->roles ) )
                return array ();
    
            return $user->roles;
        }
    
        /**
         * @return array
         */
        abstract public function get_allowed_values();
    }
    
    内置角色的扩展类
    /**
     * User roles as comment meta.
     */
    class Comment_Meta_Builtin_Roles extends Comment_Meta_Data_Model
    {
        /**
         * (non-PHPdoc)
         * @see WPSE.Comment_Meta_Data_Model::get_allowed_values()
         */
        public function get_allowed_values()
        {
            global $wp_roles;
    
            if ( empty ( $wp_roles ) )
                $wp_roles = new \\WP_Roles;
    
            $output = array();
    
            foreach ( $wp_roles->roles as $identifier => $role )
                $output[ $identifier ] = $role[\'name\'];
    
            return $output;
        }
    }
    
    用于自定义选择允许角色的扩展类
    /**
     * Custom roles for comment meta.
     */
    class Comment_Meta_Custom_Roles extends Comment_Meta_Data_Model
    {
        /**
         * (non-PHPdoc)
         * @see WPSE.Comment_Meta_Data_Model::get_allowed_values()
         */
        public function get_allowed_values()
        {
            return array (
                \'teacher\' => \'Teacher\',
                \'student\' => \'Student\'
            );
        }
    }
    
    基本评论元视图
    /**
     * Base class to show comment meta data.
     */
    class Comment_Meta_View
    {
        /**
         * Model
         *
         * @type Comment_Meta_Data_Model
         */
        protected $data;
    
        /**
         * Constructor.
         *
         * @param Comment_Meta_Data_Model $data
         */
        public function __construct( Comment_Meta_Data_Model $data )
        {
            $this->data = $data;
        }
    }
    
    使用选择字段作为视图
    /**
     * Show role selector from comment meta
     */
    class Comment_Meta_Role_Selector extends Comment_Meta_View
    {
        /**
         * Add \'select\' field before textarea.
         *
         * @param  string $text_field
         * @return string
         */
        public function show( $text_field )
        {
            return $this->get_select() . $text_field;
        }
    
        /**
         * Select element.
         *
         * @return string
         */
        public function get_select()
        {
            $allowed = $this->data->get_allowed_values();
            $current = $this->data->get_current_value();
            $key     = $this->data->get_key();
    
            // is the current value part of the allowed values?
            if ( ! empty ( $current ) && array() !== array_intersect( $allowed, $current ) )
                return $this->get_hidden_field( $key, $current[0] );
    
            $select = \'<p>\';
            $select .= sprintf( \'<label for="%1$s_id">Your role:</label>
                <select name="%1$s" id="%1$s_id">\',
                $key
            );
            $select .= \'<option value="">Select a role</option>\';
    
            foreach ( $allowed as $internal => $display )
                $select .= sprintf(
                    \'<option value="%1$s">%2$s</option>\',
                    \\esc_attr( $internal ),
                    \\esc_html( $display )
                );
    
            return $select . \'</select></p>\';
        }
    
        /**
         * Print preselcted role as hidden input field.
         *
         * @param  string $name Field name
         * @param  string $role Internal role name
         * @return string
         */
        protected function get_hidden_field( $name, $role )
        {
            return sprintf(
                \'<input type="hidden" name="%1$s" value="%2$s">\',
                $name,
                esc_attr( $role )
            );
        }
    
        /**
         * Callback for do_action.
         *
         * @wp-hook comment_role_selector
         * @return  void
         */
        public function print_select()
        {
            print $this->get_select();
        }
    }
    
    将当前角色显示为视图
    /**
     * Show current comment role.
     */
    class Comment_Meta_Role_Display extends Comment_Meta_View
    {
        /**
         * Add role to comment text.
         *
         * @wp-hook comment_text
         * @param   string $text
         * @param   object $comment
         * @return  string
         */
        public function show( $text, $comment )
        {
            $role = $this->data->get_comment_meta( $comment->comment_ID );
    
            if ( \'\' !== $role )
                $text = "Role: $role<br> $text";
    
            return $text;
        }
    
        /**
         * Print the comment meta value into a template.
         *
         * Usage: <code>do_action( \'comment_role_value\', \'Role: %s<br>\', $comment );
         *
         * @wp-hook comment_role_value
         * @param   string $template
         * @param   object $comment
         * @return  void
         */
        public function show_action( $template, $comment )
        {
            $role = $this->data->get_comment_meta( $comment->comment_ID );
    
            if ( \'\' !== $role )
                printf( $template, $role );
        }
    }
    
    如你所见,我们现在有七节课:

    1. Comment_Meta_Controller
      在这里,其他类被结合起来做一些有用的事情
    2. Comment_Meta_Data_Model处理注释数据的基类。不能按原样使用,必须扩展
    3. Comment_Meta_Builtin_Roles
      扩展Comment_Meta_Data_Model 并使用所有内置角色。我已经在测试中使用了它;您可能应该使用下一个类。更改控制器以执行此操作
    4. Comment_Meta_Custom_Roles
      扩展Comment_Meta_Data_Model. 替代方案Comment_Meta_Builtin_Roles.
      如您所见,只需更改一个方法(函数)即可返回自定义角色数组
    5. Comment_Meta_View
      输出的基类。不能按原样使用,必须扩展
    6. Comment_Meta_Role_Selector
      扩展Comment_Meta_View. 创建select 要素它不知道数据源的任何信息,只从视图中获取其值
    7. Comment_Meta_Role_Display
      扩展Comment_Meta_View. 显示注释的当前值

    用法show the select field 要么…

    什么都不做,让我的默认值来完成工作。然后,选择字段将设置在注释文本字段的正上方

    \\add_filter( \'comment_form_field_comment\', array ( $input, \'show\' ), 10, 2 );
    
    …并在评论表单中使用以下代码:

    do_action( \'comment_role_selector\' );
    
    set custom values 对于允许的角色,请删除该行…

        $data   = new Comment_Meta_Builtin_Roles( \'_comment_role\' );
    
    …并取消对以下行的注释。然后编辑Comment_Meta_Custom_Roles.

    change the meta key, 只需更改值\'_comment_role\'. 确保不要使用WordPress的内置键。

    仅此而已。

    结束