web-dev-qa-db-ja.com

配列内に1つの値を持つ繰り返し可能フィールドを保存する方法を教えてください。

導入私は現在PHPとWordPressの多くを学ぶためにスライダープラグインに取り組んでいます。私はJavaScriptでいくつかの繰り返し可能なフィールドを作成しました。

いくつかの機能詳細:

  • ユーザーがボタンをクリックすると、最後の行が複製され、すべての値がリセットされます。
  • 私の入力名とIDのためにユニークなIDを作成するためにJavaScriptコードに増加を加えてください。
  • 複製された行に一意のIDを追加します。

問題:私はこのトピックを書きました、なぜなら私は配列の中の一つの変数から値を保存することに関していくつかの問題があるからです。

投稿またはページを保存すると、最初のフィールドが上書きされます。これは、$_POST変数ではなく、1つの画像と1つのキャプションをループ処理するためです。

質問:私の質問は、この問題を解決する方法です。 @brasofiloが Github - Gist で推奨しているソースコードも調べました。 Brasofiloはメタを1つしか使用していませんが、フィールドを作成するために多次元配列を使用したいと思います。そして、データベースの1行に値を配列として保存します。

私は私が他のいくつかのプラグインを利用できることを知っています、しかし私が以前に述べたように私は多くのWordPressとPHPスクリプト言語を学びたいです。

スクリプトPHP:

ここで、私が使用したコードを今のところ見ることができます。前に述べたように、1つの画像と1つのキャプションしか保存されません。

<?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

あなたのフォームがこのようなものを見ているなら:

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

そしてインデックスをインクリメントして繰り返します。

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

それでは後で手に入れるものは次のようなものです。

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

それからsave_postであなたは以下のことを確認することができます:

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

その後、whileループで$custom_meta_fieldsをループ処理できます。

$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++;
}

すべての面を検証したら、それらを1つのオプションフィールドに保存できます。

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

ちなみに、$ _POST ['fields']に関しては、次のように配列を設定できます。

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

それでもあなたはまだループすることができます。

1
NightHawk

1つの画像と1つの画像キャプションのみを保存しています。 dsslider_manager_save_extras関数のループは、phpファイルで定義されているグローバル$ custom_meta_fieldをループします。 $ _POST変数を通してではありません。あなたのループは次のようになります。

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

HTMLでは、フォームは次のようになります。

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

あなたはここでこのトピックについてもっと読むことができます: https://stackoverflow.com/questions/2433727/submitting-a-multidimensional-array-via-post-with-php

1
david.binda