web-dev-qa-db-fra.com

Ajouter une liste déroulante au formulaire de commentaire?

Quelqu'un peut-il m'aider à créer un menu déroulant ou des (boutons radio) sous la forme d'un commentaire Wordpress, afin qu'un nouvel utilisateur puisse sélectionner ses rôles (par exemple enseignants + étudiants)?

  1. La sortie de la liste déroulante ou du bouton radio apparaîtrait quelque part dans la zone de commentaires.
  2. Le meilleur de tous serait également si WordPress qui peuplent déjà automatiquement
    courriel, le nom de connexion afficherait également de nouvelles informations sur les champs supplémentaires (liste déroulante OU
    bouton radio) pour connecter les utilisateurs auxquels leurs rôles d'utilisateur ont déjà été attribués
  3. Je ne veux pas utiliser de plugin pour ça.
  4. Je sais qu'il existe de nombreux tutoriels sur l'ajout de champs personnalisés supplémentaires au formulaire de commentaire, y compris ce site Web où trois requêtes similaires ont malheureusement été signalées comme des doublons. À mon avis, ce ne sont pas des dupes, car il n'y a pas de code ou de tutoriel pour les utiliser les valeurs connues en tant que bouton (sélectionner - liste déroulante - radio).
2
Daniel Foltynek
  • Filtrez comment_form_field_comment pour ajouter un élément select avec un label.
  • Ajoutez un rappel à l'action comment_post pour enregistrer la valeur.
  • Filtrez comment_text pour afficher la valeur d'un commentaire.

Exemple de code:

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 );

Mettre à jour

J'ai réécrit le code pour utiliser un vrai modèle MVC. Explication ci-dessous. As plugin dans GitHub .

En-tête de plugin

<?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' )
);

Manette

/**
 * 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' ) );
    }
}

Classe de base de métadonnées abstraite

/**
 * 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();
}

Classe étendue pour les rôles intégrés

/**
 * 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;
    }
}

Classe étendue pour la sélection personnalisée des rôles autorisés

/**
 * 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'
        );
    }
}

Méta vue de commentaire de base

/**
 * 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;
    }
}

Utiliser un champ de sélection comme vue

/**
 * 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();
    }
}

Afficher le rôle actuel en tant que vue

/**
 * 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 );
    }
}

Comme vous pouvez le constater, nous avons maintenant sept classes:

  1. Comment_Meta_Controller
    Ici, les autres classes sont combinées pour faire quelque chose d’utile.
  2. Comment_Meta_Data_Model Classe de base pour gérer les données de commentaire. Ne peut être utilisé tel quel, doit être étendu.
  3. Comment_Meta_Builtin_Roles
    Etend Comment_Meta_Data_Model et utilise tous les rôles intégrés. Je l'ai utilisé pour mes tests. vous devriez probablement utiliser la classe suivante. Changer le contrôleur pour le faire.
  4. Comment_Meta_Custom_Roles
    Etend Comment_Meta_Data_Model. Une alternative pour Comment_Meta_Builtin_Roles.
    Comme vous pouvez le constater, vous devez modifier une seule méthode (fonction) pour renvoyer un tableau de rôles personnalisés.
  5. Comment_Meta_View
    Classe de base pour la sortie. Ne peut être utilisé tel quel, doit être étendu.
  6. Comment_Meta_Role_Selector
    Etend Comment_Meta_View. Crée l'élément select. Il ne sait rien de la source de vos données et obtient ses valeurs directement dans la vue.
  7. Comment_Meta_Role_Display
    Etend Comment_Meta_View. Affiche la valeur actuelle d'un commentaire.

Usage

Pourafficher le champ selectsoit…

  • Ne rien faire et laisser mes défauts faire le travail. Le champ de sélection sera défini juste au-dessus du champ de texte de commentaire.
  • Ou supprimez la ligne…

    \add_filter( 'comment_form_field_comment', array ( $input, 'show' ), 10, 2 );
    

    … Et utilisez dans votre commentaire ce code:

    do_action( 'comment_role_selector' );
    

Pourdéfinir des valeurs personnaliséespour les rôles autorisés, supprimez la ligne…

    $data   = new Comment_Meta_Builtin_Roles( '_comment_role' );

… Et décommentez la ligne suivante. Puis éditez Comment_Meta_Custom_Roles.

Pourchanger la clé méta, changez simplement la valeur '_comment_role'. Assurez-vous de ne pas utiliser une clé intégrée de WordPress.

C'est tout.

6
fuxia