2
votes

english is not my native language but I try my best to descripe my problem to you.

Iam working on a plugin for WooCommerce, I dont think that is really relevant but anyway...

I have set-up an custom-post-type, and also assigned a custom-taxonomy to that post-type.

For each custom-taxonomy-term I create an metabox on the product-type. Every metabox is unique cause I pass the term-slug.

function add_post_meta_boxes() {

    $args = array(
        'type'      => 'product',
        'taxonomy'  => 'picto_group',
        'orderby'   => 'term_group',
        'order'     => 'ASC'
    );
    $groups = get_categories($args);

    foreach($groups as $group) { 

        // 
        $slug = $group->slug;
        $name = $group->name;
        $count = $group->category_count;
        $desc = $group->category_description;
        $catid = $group->cat_ID;

        add_meta_box(
            'i3_picto_'.$slug,      // Unique ID
            $name.' - '.$count,    // Title
            'i3_picto_meta_box', // Callback function
            'product',         // Admin page (or post type)
            'normal',         // Context
            'low',         // Priority
            array($slug, $catid, $desc)// Arguments to pass into the callback function
        );
    }// End foreach
}

This metabox is than filled with all the posts which have the custom-term.

function i3_picto_meta_box( $object, $box ) { 

    $slug = $box['args'][0];
    $catid = $box['args'][1];
    $desc = $box['args'][2];
    ?>

    <p>

        <?php
        $args = array( 
            'post_type' => 'product_picto', // Post-Type name
            'numberposts'   => -1,
            'tax_query' => array(
                array(
                    'taxonomy' => 'picto_group', // Taxonomy name
                    'field' => 'id',
                    'terms' => $catid // Term ID
                )
              )
        );
        $pictograms = get_posts( $args );

        foreach ( $pictograms as $pictogram ) :
          setup_postdata( $pictogram ); 

            $pslug = $pictogram->post_name;

            $checked = get_post_meta($pictogram->ID, 'cb-one[cb-'.$slug.'_'.$pslug.']', true);  
        ?>

            <div class="group-<?php echo $slug; ?>-<?php echo $pslug; ?>">
                <label for="cb-<?php echo $slug; ?>_<?php echo $pslug; ?>">
                    <?php echo get_the_post_thumbnail( $pictogram->ID, 'thumbnail' ); ?>
                    <?php the_title(); ?>   
                    <?php the_content(); ?>
                    <input type="checkbox" name="cb-one[cb-<?php $slug; ?>_<?php $pslug;?>']" id="cb-<?php echo $slug; ?>_<?php echo $pslug; ?>" <?php if( $checked == true ) { ?>checked="checked"<?php } ?> />
                </label>
            </div>

        <?php
        endforeach; 
        wp_reset_postdata();
        ?>
    </p>
<?php }

All posts show the title, thumbnail and content.

I will also display a check box in every post. So as I edit some products, I am able to check some post of some categories. In the end these post should show also in the front end.


Now I am having big trouble with how I can save the state for every check box. Because all my metaboxes are auto-generated, and as you can see also my checkbox-field has an auto-generated name of "term-slug" + "post-slug".

How can I pass the generated check box-field name to my save_post function?

I think I named my check box-fields in the wrong way and I also think I need to run an foreach-loop on the update_post_meta in my save function?

Maybe I am thinking too complicated here.

Maybe someone can understand this and have some useful information for me.

Thanks, Mo


UPDATE

Hey guys,

so today I worked on and updated my code. I can now already save my metaboxes and also the checked state. But something is not quite right yet.

I hope its ok that I edit my Question instead of commenting.

The new checkbox code looks like this:

<input type="checkbox" name="cb-one[]" id="cb-<?php echo $slug; ?>_<?php echo $pslug; ?>" value="<?php echo $pid; ?>" <?php checked( in_array( $pid, $pictoarray ) ); ?> />

And the function to save the metabox looks like this:

function i3_save_post_class_meta( $post_ID ) {

    global $post;

    if(isset( $_POST['cb-one'] ))
    {
        $custom = $_POST['cb-one'];
        $old_meta = get_post_meta($post->ID, '_cb-one');
        // Update post meta
        if(!empty($old_meta)){
            update_post_meta($post->ID, '_cb-one', $custom );
        } else {
            add_post_meta($post->ID, '_cb-one', $custom );
        }
    }
}

To be able to also get the checked=checked state of the single checkboxes I added this code to the top of my i3_picto_meta_box function:

global $post;
$pictolist = get_post_meta( $post->ID, '_cb-one');
if (!empty($pictolist[0])) {
    $pictoarray = $pictolist[0]; // Get the right array
}

Here Iam getting the metadata as an array and on the input element I check if the value of that element is also in that array.

With these updates I can now select multiple checkboxes in my post/product. The ID´s of the selected posts get saved and I can also retrieve them in the frontend.

Iam working with checkboxes becaus I want to be able to also uncheck them in the future.

So I tried this, I selected multiple checkboxes and saved the post. After that I unchecked every checkbox and saved again.

Unfortunatly all checkboxes stayed checked!

Than I unchecked just one box and saved, everything was fine. I continued with this one-by-one just to find out, that everytime the last checkbox always stays checked.

I can uncheck all boxes except one. As soon as I save the post one checkbox will still be checked.

I hope someone can help me fix this problem.

Thanks, Mo

1
Not an answer, so I apologize, but you should use Custom Post Type UI plugin (and advanced custom fields plugin). I know one shouldn't rely on plugins, but I used these two plugins on my last quick turnaround freelance project and man, did they help. I am a convert. They are so powerful that not using them almost constitutes a NIH fallacy... at least that is my opinion... but what do I know I am not a hardcore WP dev.picus
Hi picus, thanks for the suggestion. But Iam also trying to learn a little bit here :). As you can see my code is not the cleanest one and Iam trying to improve in this. But as always, just after posting this question I got it down now! Will edit my post in a minute.LWS-Mo
awesome good to hear. I would check them for your next project, they really come in handy wen you have a few content types to build.picus

1 Answers

0
votes

As nearly always after asking a question, I found the solution ;)

I did it. The problem was simply in my save function. The function was set to add some metadata when no checkbox is checked.

So I changed it to this:

/**
 * Saving the meta-boxes
 **/
function i3_save_post_class_meta( $post_ID ) {

    global $post;

    if(isset( $_POST['cb-one']))
    {
        $custom = $_POST['cb-one'];
        $old_meta = get_post_meta($post->ID, '_cb-one');
        // Update post meta
        //if(!empty($old_meta)){
            update_post_meta($post->ID, '_cb-one', $custom );
        //} 
    }else{
        delete_post_meta($post->ID, '_cb-one', $custom  );
    }

}

Hope this also can help some other folks.