0

I'm working on a theme for a magazine publisher who routinely deals with a large number of images. I need them to be able to associate each image with a contributor (photographer, illustrator, artist, etc.)

Each contributor is contained in a custom post type, 'jdp_contributors' and the contributor type is a custom taxonomy, 'jdp_contributor_types'.

Using the WordPress hook 'attachment_fields_to_edit' I would like to add a select menu that allows the user to choose a contributor for the image. I have the site spitting out the menu and saving the values correctly, but there are a couple of strange bugs going on.

1) When adding a new image via the media uploader the full list of (50+) contributors is available to select from.

2) When editing an image via the media uploader (in the 'Media Gallery') tab, only the first 10 contributors are available for selection.

To create the select menu I am creating an new instance of WP_QUERY. The arguments for WP_QUERY state that 'posts_per_page' = -1 and 'nopaging' is set to true.

I'm at a loss as to what I'm not doing correctly.

<?php
/**
* Add Photographer selection to media upload
*
* @param $form_fields array, fields to include in attachment form
* @param $post object, attachment record in database
* @return $form_fields, modified form fields
*/
function bsj_attachment_field_credit( $form_fields, $post ) {
    //do_dump($post);

    $form_fields['jdp_photographer'] = array(
        'label' => 'Contributor:',
        'input' => 'html',
        'helps' => 'Choose the photographer/artist for this image',
    );

    //GET THE CURRENT PHOTOGRAPHER
    $current_photog = get_post_meta($post->ID, 'jdp_photographer', true);
    if ( !isset($current_photog) ) {
        $current_photog = 0;    
    }

    //SETUP THE FORM FIELD
    $form_fields['jdp_photographer']['html'] = '<select name="attachments['.$post->ID.'][jdp_photographer]" id="attachments['.$post->ID.'][jdp_photographer]">';

    //OUTPUT NULL FIELD
    $form_fields['jdp_photographer']['html'] .= '<option value="0" '.selected(0, $current_photog, false).'>Choose one...</option>';

    //GET THE TERMS IN THE 'jdp_contributor_types' taxonomy, excluding authors
    $terms = get_terms( 'jdp_contributor_types', array('fields' => 'ids', 'hide_empty' => false, 'exclude' => '32') );

    //GET THE PHOTOGRAPHERS
    $args = array(
        'post_type' => 'jdp_contributors',
        'nopaging' => true,
        'posts_per_page' => -1,
        'tax_query' => array(
            array(
                'taxonomy' => 'jdp_contributor_types',
                'field' => 'id',
                'terms' => $terms
            ),
        ),
        'orderby' => 'name',
        'order' => 'ASC',
    );
    $photographers = new WP_QUERY($args);

    //LOOP THRU THE PHOTOGRAPHERS
    foreach( $photographers as $postdata ) {
        setup_postdata($postdata);
        $form_fields['jdp_photographer']['html'] .= '<option value="'.$postdata->ID.'" '.selected($postdata->ID, $current_photog, false).'>'.$postdata->post_title.'</option>';
    }
    wp_reset_query();

    $form_fields['jdp_photographer']['html'] .= '</select>';

    return $form_fields;
}
add_filter( 'attachment_fields_to_edit', 'bsj_attachment_field_credit', 10, 2 );


/**
* Save values of Photographer Name and URL in media uploader
*
* @param $post array, the post data for database
* @param $attachment array, attachment fields from $_POST form
* @return $post array, modified post data
*/
function jdp_attachment_field_credit_save( $post, $attachment ) {
    if (isset( $attachment['jdp_photographer'] ) )
        update_post_meta( $post['ID'], 'jdp_photographer', $attachment['jdp_photographer'] );

    return $post;
}
add_filter( 'attachment_fields_to_save', 'jdp_attachment_field_credit_save', 10, 2 );
?>
1
  • On a whim I chose to use the get_posts() function instead of creating a new instance of WP_QUERY and this method seems to work. As I'm not able to post code in a comment, please contact me if you need full code examples. Not quite sure how to mark this as solved however... Aug 10, 2012 at 16:09

1 Answer 1

0

I'm not entirely sure why the get_posts() function works instead of creating a new instance of WP_QUERY. From what I understand about how WordPress queries work, get_posts() is actually creating it's own instance of WP_QUERY anyhow.

Either way, here is the solution that I'm using currently.

<?php
    //GET THE PHOTOGRAPHERS
    $args = array(
        'post_type' => 'jdp_contributors',
        'numberposts' => -1,
        'tax_query' => array(
                    array(
                        'taxonomy' => 'jdp_contributor_types',
                        'field' => 'id',
                        'terms' => $terms
                    ),
        )
    );
    $photographers = get_posts($args);

    //LOOP THRU THE PHOTOGRAPHERS
    foreach( $photographers as $post ) {
        $form_fields['jdp_photographer']['html'] .= '<option value="'.$post->ID.'" '.selected($post->ID, $current_photog, false).'>'.$post->post_title.'</option>';
    }
?>
1
  • for future reference, if you print_r($photographers); after your WP_Query, you can see how the params are interpreted and the actual SQL query being generated and sent to the database. it's possible something is hooking the query and modifying it via a filter, get_posts suppresses filters by default.
    – Milo
    Aug 10, 2012 at 17:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.