Im pretty new to php and have some issues with my code.
Ive been struggling with this for a few days now, researching, editing with no luck…
Please help a bro and explain how to solve my problem!!
Purpose with code
Adding custom meta fields to the dashboard post page so the user can add image(s) to a post.
ISSUES
The code works but is not 100% functional.
When adding images to the meta fields following happens
- Adding ONLY one image, everything works.
- Adding MORE than one image, the last image “src field” gets this
error in the input field:
“…Undefined index: src in…functions.php line 123”
Line 123 is:
<td><input type="text" class="widefat" name="src[]" value="<?php if ($field['src'] != '') echo esc_attr( $field['src'] ); ?>" /></td>
and the array looks like this:
Array
(
[0] => Array
(
[title] => image-name1.gif
[alt] => image description 1
[src] => http://my-host.com/art/wp-content/uploads/2014/04/test1.gif
)
[2] => Array
(
[title] => image-nam2.gif
[alt] => image description 2
[src] => http://my-host.com/art/wp-content/uploads/2014/04/test3.gif
)
[3] => Array
(
[title] => image-name3.gif
[alt] => image description 3
)
)
- When adding the last image again and update the post everything
works!
Research
I think it has to be something with the function that, in some way, checks the src input field if the field got any value because it only works when the input field excists.
It could also be something wrong in the last for loop that creates the array, before saving the meta fields.
function.php:
// add meta box to screen
function add_meta_boxes() {
add_meta_box( 'image-meta-fields',
'Add Image to Post',
'image_meta_field_display',
'post',
'normal',
'high');
}
add_action('admin_init', 'add_meta_boxes', 1);
// output the meta box content
function image_meta_field_display() {
global $post;
$image_meta_fields = get_post_meta($post->ID, 'image_meta_fields', true);
wp_nonce_field( 'image_meta_field_nonce', 'image_meta_field_nonce' );
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.add-row').on('click', function() {
var row = $('.empty-row.screen-reader-text').clone(true);
row.removeClass('empty-row screen-reader-text');
row.insertBefore('#image-meta-field-one tbody>tr:last');
return false;
});
$('.remove-row').on('click', function() {
$(this).closest('tr').next().remove();
$(this).closest('tr').remove();
return false;
});
//
$('.add-image').click(function() {
var send_attachment_bkp = wp.media.editor.send.attachment;
var button = $(this);
wp.media.editor.send.attachment = function(props, attachment) {
$(button).closest('tr').prev().children('td').eq(0).find('input').val(attachment.title); //set title
$(button).closest('tr').prev().children('td').eq(1).find('input').val(attachment.alt); // set alt (description)
$(button).closest('td').prev().children().val(attachment.url); // set url
wp.media.editor.send.attachment = send_attachment_bkp;
}
wp.media.editor.open();
return false;
});
});
</script>
<table id="image-meta-field-one" width="100%">
<thead>
<tr>
<th width="30%">Name</th>
<th width="50%">Description</th>
<th width="10%"></th>
</tr>
</thead>
<tbody>
<?php
if ( $image_meta_fields ) :
foreach ( $image_meta_fields as $field ) {
?>
<tr>
<td><input type="text" class="widefat" name="title[]" value="<?php if ($field['title'] != '') echo esc_attr( $field['title'] ); ?>" /></td>
<td><input type="text" class="widefat" name="alt[]" value="<?php if ($field['alt'] != '') echo esc_attr( $field['alt'] ); ?>" /></td>
<td><a class="button remove-row" href="#">DEL</a></td>
</tr>
<tr>
<th width="30%"></th>
<td><input type="text" class="widefat" name="src[]" value="<?php if ($field['src'] != '') echo esc_attr( $field['src'] ); ?>" /></td>
<td><a class="button add-image" href="#" value="" >ADD IMAGE</a></td>
</tr>
<?php
}
else :
// show a blank one
?>
<tr>
<td><input type="text" class="widefat" name="title[]" /></td>
<td><input type="text" class="widefat" name="alt[]" /></td>
<td><a class="button remove-row" href="#">DEL</a></td>
</tr>
<tr>
<th width="30%"></th>
<td><input type="text" class="widefat" name="src[]" value=""/></td>
<td><a class="button add-image" href="#">ADD IMAGE</a></td>
</tr>
<?php endif; ?>
<!-- empty hidden one for jQuery -->
<tr class="empty-row screen-reader-text">
<td><input type="text" class="widefat" name="title[]" /></td>
<td><input type="text" class="widefat" name="alt[]" /></td>
<td><a class="button remove-row" href="#">DEL</a></td>
</tr>
<tr class="empty-row screen-reader-text">
<th width="30%"></th>
<td><input type="text" class="widefat" name="src[]" value="" /></td>
<td><a class="button add-image" href="#">ADD IMAGE</a></td>
</tr>
</tbody>
</table>
<p><a class="button add-row" href="#">Add More Images</a></p>
<?php
}
add_action('save_post', 'image_meta_field_save');
function image_meta_field_save($post_id) {
if ( !isset( $_POST['image_meta_field_nonce'] ) ||
! wp_verify_nonce( $_POST['image_meta_field_nonce'], 'image_meta_field_nonce' ) )
return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if (!current_user_can('edit_post', $post_id))
return;
$old = get_post_meta($post_id, 'image_meta_fields', true);
$new = array();
$titles = $_POST['title'];
$alts = $_POST['alt'];
$srcs = $_POST['src'];
$count = count( $titles );
for ( $i = 0; $i < $count; $i++ ) {
if ( $titles[$i] != '' ) :
$new[$i]['title'] = wp_filter_post_kses( $titles[$i] );
if ( $alts[$i] != '' )
$new[$i]['alt'] = wp_filter_post_kses ( $alts[$i] );
if ( $srcs[$i] != '' )
$new[$i]['src'] = wp_filter_post_kses( $srcs[$i] );
endif;
}
if ( !empty( $new ) && $new != $old )
update_post_meta( $post_id, 'image_meta_fields', $new );
elseif ( empty($new) && $old )
delete_post_meta( $post_id, 'image_meta_fields', $old );
}
Outputting the meta array in the front-end like this:
<?php
$get_images = get_post_meta( get_the_id(), 'image_meta_fields', true );
if ( !empty( $get_images ) ) {
foreach ( $get_images as $key => $image ) :
if ( $key === 0 )
echo "<img class='post-image' title='" . $image['title'] . "' alt='" . $image['alt'] . "' src='" . $image['src'] . "'/>";
else
echo "<img class='post-thn' title='" . $image['title'] . "' alt='" . $image['alt'] . "' src='" . get_image_thumbnail($image['src']) ."'/>";
endforeach;
}
?>
Inspecting this variables:
I saw that
$titles
and$alts
were coming out of order:The problem is when you clone this block:
It becomes this:
Instead of this:
It can be solved adding an ID to the first
<tr>
:And adjusting this in
$('.add-row').on('click', ...);
: