新しいユーザが自分のユーザロールを選択できるように、ドロップダウンメニューまたは(ラジオボタン)をWordpressのコメントフォームに作成する手助けをすることができますか(例:教師+生徒)。
select
を持つlabel
要素を追加するためにcomment_form_field_comment
をフィルタリングします。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パターンを使用するようにコードを書き直しました。以下の説明GitHubで プラグインとして 。
<?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: Thomas Scholz
* Author URI: http://toscho.de
* 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 );
}
}
ご覧のとおり、現在7つのクラスがあります。
Comment_Meta_Controller
Comment_Meta_Data_Model
コメントデータを扱うための基本クラス。そのまま使用することはできません、拡張する必要があります。Comment_Meta_Builtin_Roles
Comment_Meta_Data_Model
を拡張し、すべての組み込みロールを使用します。私はこれを私のテストに使いました。おそらく次のクラスを使うべきです。そうするためにコントローラを変更してください。Comment_Meta_Custom_Roles
Comment_Meta_Data_Model
を拡張します。 Comment_Meta_Builtin_Roles
の代替。Comment_Meta_View
Comment_Meta_Role_Selector
Comment_Meta_View
を拡張します。 select
要素を作成します。データのソースについては何も知りませんし、その値をビューから正しく取得できます。Comment_Meta_Role_Display
Comment_Meta_View
を拡張します。コメントの現在の値を表示します。にselect
フィールドを表示するどちらか…
または行を削除してください…
\add_filter( 'comment_form_field_comment', array ( $input, 'show' ), 10, 2 );
…そしてあなたのコメントフォームで次のコードを使ってください:
do_action( 'comment_role_selector' );
許可されたロールにカスタム値を設定するに、行を削除してください…
$data = new Comment_Meta_Builtin_Roles( '_comment_role' );
…そして次の行のコメントを外します。それからComment_Meta_Custom_Roles
を編集してください。
にメタキーを変更し、値'_comment_role'
を変更するだけです。 WordPressの内蔵キーを使用しないでください。
それで全部です。