web-dev-qa-db-fra.com

Comment puis-je enregistrer des champs répétables avec une valeur dans un tableau?

Introduce Je travaille actuellement sur un plugin de curseur pour apprendre beaucoup de PHP et WordPress. J'ai créé des champs reproductibles avec javascript.

Quelques détails fonctionnels:

  • Lorsque l'utilisateur clique sur un bouton, la dernière ligne est clonée et toutes les valeurs sont réinitialisées.
  • Ajoutez une augmentation au code javascript pour créer des identifiants uniques pour mes noms d'entrée et identifiants.
  • Ajoutez un identifiant unique pour mes lignes clonées.

Le problème: J'ai écrit cette rubrique, car l'enregistrement de valeurs d'une variable dans un tableau pose certains problèmes.

Lorsque je sauvegarde le message ou la page, le premier champ est écrasé. En effet, je parcourais une image et une légende, et non la variable $_POST.

Question: Ma question est maintenant comment je peux résoudre ce problème? J'ai également examiné le code source recommandé par @brasofilo sur Github - Gist . Brasofilo n'a utilisé qu'une méta, mais j'aimerais utiliser un tableau multidimensionnel pour créer mes champs. Et enregistrez les valeurs sur une ligne de la base de données sous forme de tableau.

Je sais que je peux utiliser plusieurs autres plugins, mais comme je l’ai déjà dit, je voudrais apprendre beaucoup de WordPress et le langage de script PHP.

Script PHP:

Ici, vous pouvez voir mon code utilisé pour le moment, comme je l’ai déjà dit, il n’enregistre qu’une image et une légende.

<?php

// Add meta box support
// This registers a function to be called when the WordPress admin interface is visited
add_action("admin_init", "dsslider_manager_add_meta");
function dsslider_manager_add_meta(){

    // Create this cool new meta box for Portfolio Options
    add_meta_box("dsslider-meta", "Brandbox Options", "dsslider_manager_meta_options", "brandbox-slider", "normal", "high");
}

// Create the fields array
$prefix = 'dsmeta_';
$custom_meta_fields = array(
    array(
        'label' => 'Image',
        'desc' => '',
        'id' => $prefix . 'image',
        'type' => 'image',
        'repeatable' => true,
    ),
    array(
        'label' => 'Image caption',
        'desc' => '',
        'id' => $prefix . 'image_caption',
        'type' => 'text',
        'repeatable' => true,
    )
);

// Callback unctions for setting up Brandbox Options
function dsslider_manager_meta_options(){

    global $custom_meta_fields, $post;
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
        // (integer) (optional) The post ID whose custom fields will be retrieved. 
        // Default: Current post
        return $post_id;

echo '<div class="dsslider_manager_extras">';

    // Markup for table head
    echo '<table class="meta ds-input-table">';
    echo '<tbody class="ui-sortable">';


    // Use nonce for verification
    echo '<input type="hidden" name="dsmeta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';

    // Begin a table row
    echo '<tr class="row" id="repeatable-[0]">';
    echo '<td class="order">1</td>';

    foreach ($custom_meta_fields as $field) {
        // Get value of this field if it exists for this post
        $meta = get_post_meta($post->ID, $field['id'], true);
        $type = $field['type'];

        // Each $meta in an table data
        echo '<td>';

        // Check if value repeatable is set
        if ($field['repeatable']) {

            switch ($type) {
                // Image case
                case 'image':

                    $image = get_template_directory_uri() . '/assets/images/default.jpg'; // Default image for the preview
                    echo '<span class="default_image" style="display:none">' . $image . '</span>';

                    // If $meta == (equal to) true
                    if ($meta) {
                        $image = wp_get_attachment_image_src($meta, 'thumbnail');
                        $image = $image[0]; // Get the first key of the array - url
                    } // End if

                    echo '<input type="hidden" name="' . $field['id'] . '" class="upload_image" value="' . $meta . '" />'; // Save the image ID
                    echo '<img src="' . esc_attr( $image ) . '" alt="" class="preview_image" />'; // Preview uploaded image
                    echo '<input type="button" class="button add-image" value="Add image" rel="' . get_the_ID() . '" />'; // Add image
                    echo '<small><a href="#" class="remove-image">Remove image</a></small>'; // Delete image

                break;

                // Text case
                case 'text':
                    echo '<input type="text" name="' . $field['id'] . '[]' . '" id="' . $field['id'] . '" value="' . $meta . '" size="30" /> ';
                break;

            } // End switch statement

        } // End if

        echo '</td>';

    } // End foreach loop

    echo '<td class="remove"><a class="repeatable-remove button" href="#">-</a></td>';
    echo '</tr>'; // End .row


    echo '</tbody>'; // End tbody
    echo '</table>'; // End tbody

    echo '<ul class="hl clearfix ds-repeater-footer"><li class="right">';
    echo '<a href="#" class="repeatable-add ds-button">Add New Slide</a>';
    echo '</li></ul>';

echo '</div>'; // End .dsslider_manager_extras
}

// Save the data
add_action('save_post', 'dsslider_manager_save_extras');
function dsslider_manager_save_extras($post_id) {

    global $custom_meta_fields;

    // Check autosave function
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return $post_id;
    } // End if statement

    // Check permissions
    if ('page' == 'post_type') {
        if (!current_user_can('edit_page', $post_id)) {
            return $post_id;
        }
        elseif (!current_user_can('edit_post', $post_id)) {
            return $post_id;
        }
    } // End if statement

    // Loop through fields and save the data  
    foreach ($custom_meta_fields as $field) {
        if (isset($_POST[$field['id']])) {
            $old = get_post_meta($post_id, $field['id'], true);
            $new = $_POST[$field['id']];

            if ($new && $new != $old) {
                update_post_meta($post_id, $field['id'], $new);
            }
            elseif ('' == $new && $old) {
                delete_post_meta($post_id, $field['id'], $old);
            }
        } // End if statement
    } // End foreach loop
}
3
Casper

Si votre formulaire ressemble à quelque chose comme ça:

<input type="text" name="fields[0]['image']" value="" />
<input type="text" name="fields[0]['caption']" value="" />

Et répété en incrémentant l'index:

<input type="text" name="fields[1]['image']" value="" />
<input type="text" name="fields[1]['caption']" value="" />

Ensuite, vous obtiendrez plus tard quelque chose comme ceci:

$_POST['fields'] = array(
  0 => array(
    'image' => (value here)
    'caption' => (value here)
  ),
  1 => array(
    'image' => (value here)
    'caption' => (value here)
  )
);

Ensuite, dans save_post, vous pouvez vérifier si:

isset($_POST['fields']) && is_array($_POST['fields']) && !empty($_POST['fields'])

Ensuite, vous pouvez parcourir votre $custom_meta_fields dans une boucle while:

$index = 0;
$slides = array();

while(isset($_POST['fields'][$index])) {
  foreach($custom_meta_fields as $custom_meta_field) {
    // check if isset($_POST['fields'][$index][$custom_meta_fields['id']])
    // and anything else you want to validate
    // and then save field in $slides[$index][$custom_meta_fields['id']]
  }
  $index++;
}

Une fois que vous avez validé tous les côtés, vous pouvez les stocker dans un seul champ d’option:

update_post_meta($post_id, $option_name, $slides);

En passant, en termes de $ _POST ['fields'], vous pouvez configurer votre tableau comme suit:

$custom_meta_fields = array(
    'slides' => array(
      array(
        'label' => 'Image',
        'desc' => '',
        'id' => $prefix . 'image',
        'type' => 'image',
        'repeatable' => true,
      ),
      array(
        'label' => 'Image caption',
        'desc' => '',
        'id' => $prefix . 'image_caption',
        'type' => 'text',
        'repeatable' => true,
      )
    )
);

Ensuite, vous pouvez toujours faire une boucle.

1
NightHawk

Vous ne sauvegardez qu'une image et une légende. Votre boucle dans la fonction dsslider_manager_save_extras passe en boucle dans $ global custom_meta_fields défini dans le fichier php. Pas avec la variable $ _POST. Votre boucle devrait ressembler à quelque chose comme ça:

foreach ( $_POST['fields'] as $field ) {
...
}

En HTML, le formulaire devrait ressembler à ceci

<input type="hidden" name="fields[$field[ID]]" value=""/>

Vous pouvez en savoir plus sur ce sujet ici: https://stackoverflow.com/questions/2433727/submitting-a-multidimensional-array-via-post-with-php

1
david.binda