0

I have a series of CPTs, each with their own custom metaboxes. They all work great - display where they should, saving how they should. One issue I have found though is that they also ALL run their queries (for dropdown menus, etc) on EVERY admin page - and there's quite a lot.

I wrapped the section of code for the metabox options in conditional code:

function set_options() {
parent::set_options();
global $pagenow;
if ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) { 
$notes_query = new WP_Query(array(
'post_type' => 'session_note',
'posts_per_page' => -1, // show all
'orderby' => 'title',
'order' => 'DESC',
'no_found_rows' => true,
'cache_results' => false,
)); 
$notes_options = array();
foreach ($notes_query->posts as $note) {
$notes_options[$note->ID] = get_the_title($note->ID);
}
$speaker_query = new WP_Query(array(
'post_type' => 'speaker',
'posts_per_page' => -1, // show all
'orderby' => 'title',
'order' => 'ASC',
'no_found_rows' => true,
'cache_results' => false,
));
$speaker_options = array();
foreach ($speaker_query->posts as $speaker) {
$company = get_post_meta($speaker->ID, '_conferencer_company', true);
$speaker_options[$speaker->ID] = get_the_title($speaker->ID).' – '.get_the_title($company);
}
$this->options = array_merge($this->options, array(
'note' => array(
'type' => 'multi-select',
'label' => "Special Note",
'options' => $notes_options,),
'speakers' => array(
'type' => 'multi-select',
'label' => "Presenters",
'options' => $speaker_options,),
));
}}

...which limits the code to just when you are adding or editing a post, which saves the rest of the admin from lots of unnecessary query time. The metaboxes all load fine and save fine - BUT ALL of the queries still run on ALL of the edit/add post pages, regardless of post type.

I tried limiting the queries to specific post types:

function set_options() {
parent::set_options();
global $pagenow;
if ( isset( $_GET['post_type'] ) 
    && $_GET['post_type'] == 'session' 
    && 'post-new.php' == $pagenow || isset( $_GET['post'] ) 
    && 'session' == get_post_type( $_GET['post'] ) 
    && 'post.php' == $pagenow ) { 
        // do your metabox options thing - same code as above 
}}

('session' is one of the CPTs)

NOW, the problem... The metaboxes still show up on the edit/add post for the specific post type as required, AND the queries for the metabox options ONLY run of the specific post type pages as well - awesome - except... The metabox fields don't save when the page is updated!

What am I missing? Do I need another $pagenow for the updating process? If so, what is it?

EDIT

Added one of the option queries into the conditional code above as an example. Saving post/meta function below:

function save_post($post_id) {
if (get_post_type($post_id) != $this->slug) return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['conferencer_nonce'], plugin_basename(__FILE__))) return;
if (!current_user_can('edit_post', $post_id)) return;

foreach($this->options as $key => $option) {
if ($option['type'] == 'internal') continue;

$value = deep_trim($_POST['conferencer_'.$key]);

if ($option['type'] == 'int') $value = intval($value);
if ($option['type'] == 'money') $value = floatVal($value);
if ($option['type'] == 'multi-select') {
$values = array();
foreach ($_POST['conferencer_'.$key] as $value) { if (!empty($value)) $values[] = $value; }
$value = $values;
        }
if ($option['type'] == 'date-time') {
$date = getdate(strtotime($_POST['conferencer_'.$key]['date']));
$time = getdate(strtotime($_POST['conferencer_'.$key]['time']));
$value = mktime($time['hours'],$time['minutes'],$time['seconds'],$date['mon'],$date['mday'],$date['year']);
}
update_post_meta($post_id, '_conferencer_'.$key, $value);
}
}

Hope that offers more insight.

  • "The metabox fields don't save when the page is updated!" -- and the code you haven't posted? The code responsible for saving the data... – s_ha_dum Jun 29 '15 at 10:02
  • @s_ha_dum - I didn't think the code for saving the data would be relevant in this case - It works perfectly. It's only when I limit the queries for the metabox options to a specific CPT that I get an issue. – Andrew Vesey Jun 29 '15 at 11:41
  • Yes... "the code works perfectly except when it doesn't work in the case that I am talking about". I'm sure you are right. Not relevant. Obviously, something you have done is wrong and the minimal code you have posted is not adequate for finding the problem. If you are not going to provide additional information, good luck to you. I don't have time to burn begging you. – s_ha_dum Jun 29 '15 at 14:14
  • You're the expert. It just didn't make sense as it works fine without any condition and even when limiting to specific pages, just not CTP - and it's not the save code that has the condition on it. But hey, I'm just a noobie really and have inherited this code so not 100% sure of all of it. Thanks for the extended clarification. Will edit the question with more code. – Andrew Vesey Jun 29 '15 at 17:42
  • Is that "save" code part of a class? $this->slug is going to cause problems otherwise. – s_ha_dum Jul 2 '15 at 14:16
0

SOLVED!!

There was a separate check for CPT needed for the saving to work. So the conditional code now stands at:

    function set_options() {
parent::set_options();
global $pagenow;
if ( isset( $_GET['post_type'] ) 
    && $_GET['post_type'] == 'session' 
    && 'post-new.php' == $pagenow || isset( $_GET['post'] ) 
    && 'session' == get_post_type( $_GET['post'] ) 
    && 'post.php' == $pagenow || isset( $_POST['post_ID'] ) 
    && 'session' == get_post_type( $_POST['post_ID'] ) 
 ) { 
        // do your metabox options thing - same code as above 
}}

And now everything works as it should. It was the $_POST['post_ID'] that was needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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