Introduce
I am currently working on a slider plugin to learn a lot of PHP and WordPress.
I have create some repeatable field with javascript.
Some functional details:
- When the user is clicking on a button, the last row will cloned and
all values will reset. - Add an increase to the javascript code for create unique ids for my input names and id’s.
- Add an unique id for my rows that are cloned.
The problem:
I wrote this topic, because I have some issues with saving values from one variable in an array.
When I save the post or page, the first field will overwritten. This is because I loop through one image and one caption, not through the $_POST
variable.
Question:
My question now is how I can resolve this problem? I have also looked at the source code that @brasofilo has recommended at Github – Gist. Brasofilo has only used one meta, but I would like to use a multidimensional array to create my fields. And save the values in one row in the database as an array.
I know that I can make use of several other plugins, but as I said before I would like to learn a lot of WordPress and PHP scripting language.
Script PHP:
Here you can see my used code for now, as I said before, it only saves
one image and one caption.
<?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
}
You are saving only one image and one image caption. Your loop in dsslider_manager_save_extras function loops throught global $custom_meta_fields defined in php file. Not through $_POST variable. Your loop should look something like this:
In HTML, the form should look like this
You can read more on this topic here: https://stackoverflow.com/questions/2433727/submitting-a-multidimensional-array-via-post-with-php
If your form looking something like this:
And repeated by incrementing the index:
Then what you’ll get later is something like this:
Then in
save_post
you can check to see if:Then you can loop through your
$custom_meta_fields
in a while loop:Once you’ve validated all sides, you can store them in one option field:
By the way, in terms of $_POST[‘fields’], you could setup your array like so:
Then you can still loop.