如何在数组中保存具有一个值的可重复字段?

时间:2013-02-02 作者:Casper

Introduce我目前正在开发一个滑块插件来学习很多PHP和WordPress。我用javascript创建了一些可重复的字段。

Some functional details:

<当用户单击按钮时,最后一行将被克隆,所有值将重置
  • 增加javascript代码,为输入名称和id创建唯一id。
  • 为克隆的行添加唯一id
  • The problem:我写了这个主题,因为我在保存数组中一个变量的值时遇到了一些问题。

    当我保存帖子或页面时,第一个字段将被覆盖。这是因为我循环浏览一幅图像和一个标题,而不是通过$_POST 变量

    Question:我现在的问题是如何解决这个问题?我还查看了@brasofilo在上推荐的源代码Github - Gist. Brasofilo只使用了一个meta,但我想使用多维数组来创建字段。并将数据库中一行中的值保存为数组。

    我知道我可以使用其他几个插件,但正如我之前所说的,我想学习很多WordPress和PHP脚本语言。

    Script PHP:

    在这里,您可以看到我现在使用的代码,正如我之前所说的,它只保存一个图像和一个标题。

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

    2 个回复
    SO网友:david.binda

    您只保存一个图像和一个图像标题。dsslider\\u manager\\u save\\u extras函数中的循环通过php文件中定义的全局$custom\\u meta\\u字段循环。不是通过$\\u 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

    SO网友:NightHawk

    如果您的表单看起来像这样:

    <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\'])
    
    然后你可以在$custom_meta_fields 在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++;
    }
    
    验证所有方面后,可以将其存储在一个选项字段中:

    update_post_meta($post_id, $option_name, $slides);
    
    顺便说一句,按照$\\u 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,
          )
        )
    );
    
    然后你仍然可以循环。

    结束

    相关推荐

    Wp-content/plugins中的权限问题

    我在本地机器上安装了一个WP,试图用插件弄脏我的手。我希望从github克隆一个包含此插件代码的项目。然而,我没有插件内部的权限,作为一个没有su权限的普通用户,我无法做到这一点。(当然,我可以成为根并这样做,但我不认为这是应该的)。然后,默认情况下,WP安装中的文件夹将组设置为“tape”,这对我来说很奇怪。本地WP安装上内部文件夹的正确权限应该是什么?