wake-up-neo.com

Dropdown-Liste zum Kommentarformular hinzufügen?

Kann mir jemand helfen, ein Dropdown-Menü oder (Optionsfelder) in Wordpress-Kommentarform zu erstellen, damit ein neuer Benutzer eine Auswahl seiner Benutzerrollen treffen kann (zum Beispiel Lehrer + Schüler)?

  1. Die Ausgabe der Dropdown-Liste oder des Optionsfelds wird irgendwo im Kommentarbereich angezeigt.
  2. Am besten wäre es auch, wenn WordPress das schon automatisch befüllt
    E-Mail, Anmeldename würde auch neue zusätzliche Feldinformationen anzeigen (Dropdown-Liste ODER
    Optionsfeld ) für angemeldete Benutzer, denen bereits Benutzerrollen zugewiesen wurden
  3. Ich möchte kein Plugin dafür verwenden.
  4. Ich weiß, dass es eine Menge Tutorials zum Hinzufügen von zusätzlichen benutzerdefinierten Feldern zum Kommentarformular gibt, darunter dieses Web, in dem ich 3 ähnliche Anfragen gefunden habe, die leider als Duplikate markiert sind. Meiner Meinung nach handelt es sich dabei überhaupt nicht um Dups, da es keinen Code oder Tutorial zur Verwendung gibt bekannte Werte als (Auswahl - Dropdown - Radio) Button.
2
Daniel Foltynek
  • Filtern Sie comment_form_field_comment, um ein select-Element mit einer label hinzuzufügen.
  • Fügen Sie der Aktion comment_post einen Rückruf hinzu, um den Wert zu speichern.
  • Filtern Sie comment_text, um den Wert für einen Kommentar anzuzeigen.

Beispielcode:

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

Aktualisieren

Ich habe den Code umgeschrieben, um ein echtes MVC-Muster zu verwenden. Erklärung unten. Als Plugin in GitHub .

Plugin-Header

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

Regler

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

Abstrakte Metadatenbankklasse

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

Erweiterte Klasse für integrierte Rollen

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

Erweiterte Klasse zur benutzerdefinierten Auswahl zulässiger Rollen

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

Meta-Ansicht für Basiskommentare

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

Verwenden Sie ein Auswahlfeld als Ansicht

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

Zeigt die aktuelle Rolle als Ansicht an

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

Wie Sie sehen können, haben wir jetzt sieben Klassen:

  1. Comment_Meta_Controller
    Hier werden die anderen Klassen kombiniert, um etwas Nützliches zu tun.
  2. Comment_Meta_Data_Model Basisklasse zur Behandlung der Kommentardaten. Kann nicht verwendet werden, muss erweitert werden.
  3. Comment_Meta_Builtin_Roles
    Erweitert Comment_Meta_Data_Model und verwendet alle integrierten Rollen. Ich habe dies für meine Tests verwendet; Sie sollten wahrscheinlich die nächste Klasse verwenden. Ändern Sie dazu den Controller.
  4. Comment_Meta_Custom_Roles
    Erweitert Comment_Meta_Data_Model. Eine Alternative für Comment_Meta_Builtin_Roles.
    Wie Sie sehen, müssen Sie nur eine Methode (Funktion) ändern, um ein Array benutzerdefinierter Rollen zurückzugeben.
  5. Comment_Meta_View
    Basisklasse für die Ausgabe. Kann nicht verwendet werden, muss erweitert werden.
  6. Comment_Meta_Role_Selector
    Erweitert Comment_Meta_View. Erstellt das Element select. Es weiß nichts über die Quelle Ihrer Daten und bezieht seine Werte direkt aus der Ansicht.
  7. Comment_Meta_Role_Display
    Erweitert Comment_Meta_View. Zeigt den aktuellen Wert für einen Kommentar an.

Verwendungszweck

Umdas select Feld anzuzeigenentweder ...

  • Tun Sie nichts und lassen Sie meine Standardeinstellungen die Arbeit erledigen. Das Auswahlfeld wird dann direkt über dem Kommentartextfeld gesetzt.
  • Oder entfernen Sie die Linie ...

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

    ... und benutze in deinem Kommentar diesen Code:

    do_action( 'comment_role_selector' );
    

Umbenutzerdefinierte Wertefür die zulässigen Rollen festzulegen, entfernen Sie die Zeile ...

    $data   = new Comment_Meta_Builtin_Roles( '_comment_role' );

… Und kommentieren Sie die folgende Zeile aus. Dann Comment_Meta_Custom_Roles bearbeiten.

Umden Metaschlüsselzu ändern, ändern Sie einfach den Wert '_comment_role'. Stellen Sie sicher, dass Sie keinen integrierten Schlüssel von WordPress verwenden.

Das ist alles.

6
fuxia