# Custom post type archive - error in nav-menu-template.php

I created a custom post type called 'vehicle' using the CCTM plugin and copy/pasted archive.php to archive-vehicle.php but this has resulted in an error in my header:

Warning: in_array() expects parameter 2 to be array, null given in /home/.../public_html/wp-includes/nav-menu-template.php on line 439


I get the same error repeated for every main menu item (there are no submenus).

If I remove archive-vehicle.php and view the same posts using archive.php no errors appear.

Why would this be?

Update

Line 439 of nav-menu-template.php is

in_array( $parent_item->object_id,$queried_object->ancestors )


print_r($queried_object) right before line 439 generates the following - there's no 'ancestors' key: stdClass Object ( [labels] => stdClass Object ( [name] => Vehicles [singular_name] => Vehicle [add_new] => Add New [add_new_item] => Add New Vehicle [edit_item] => Edit Vehicle [new_item] => New Vehicle [view_item] => View Vehicle [search_items] => Search Vehicles [not_found] => No Vehicles Found [not_found_in_trash] => No Vehicles found in Trash [parent_item_colon] => Operator [all_items] => Vehicles [menu_name] => Vehicles [name_admin_bar] => Vehicle ) [description] => Each vehicle is linked to an Operator [publicly_queryable] => 1 [exclude_from_search] => [capability_type] => post [map_meta_cap] => 1 [_builtin] => [_edit_link] => post.php?post=%d [hierarchical] => 1 [public] => 1 [rewrite] => Array ( [slug] => vehicle [with_front] => 1 [pages] => 1 [feeds] => 1 [ep_mask] => 1 ) [has_archive] => 1 [query_var] => [register_meta_box_cb] => [taxonomies] => Array ( [0] => category [1] => features [2] => colours [3] => drivers ) [show_ui] => 1 [menu_position] => [menu_icon] => [can_export] => 1 [show_in_nav_menus] => 1 [show_in_menu] => 1 [show_in_admin_bar] => 1 [delete_with_user] => [cctm_hierarchical_custom] => 1 [cctm_hierarchical_includes_drafts] => [cctm_hierarchical_post_types] => Array ( [0] => operator ) [cctm_custom_columns_enabled] => 0 [post_type] => vehicle [use_default_menu_icon] => 1 [label] => Vehicles [cctm_show_in_menu] => 1 [cctm_show_in_menu_custom] => [rewrite_with_front] => 1 [permalink_action] => /%postname%/ [rewrite_slug] => [include_in_search] => 1 [include_in_rss] => 1 [cctm_enable_right_now] => 1 [custom_order] => ASC [is_active] => 1 [custom_fields] => Array ( [0] => passenger_capacity [1] => luggage_capacity [2] => hourly_rate [3] => included_milleage [4] => additional_mileage_price [5] => additional_image ) [map_field_metabox] => Array ( [passenger_capacity] => cctm_vehicledetails [luggage_capacity] => cctm_vehicledetails [hourly_rate] => cctm_vehicledetails [included_milleage] => cctm_vehicledetails [additional_mileage_price] => cctm_vehicledetails [additional_image] => cctm_default ) [original_post_type_name] => vehicle [name] => vehicle [cap] => stdClass Object ( [edit_post] => edit_post [read_post] => read_post [delete_post] => delete_post [edit_posts] => edit_posts [edit_others_posts] => edit_others_posts [publish_posts] => publish_posts [read_private_posts] => read_private_posts [read] => read [delete_posts] => delete_posts [delete_private_posts] => delete_private_posts [delete_published_posts] => delete_published_posts [delete_others_posts] => delete_others_posts [edit_private_posts] => edit_private_posts [edit_published_posts] => edit_published_posts [create_posts] => edit_posts ) ) stdClass Object ( [labels] => stdClass Object ( [name] => Vehicles [singular_name] => Vehicle [add_new] => Add New [add_new_item] => Add New Vehicle [edit_item] => Edit Vehicle [new_item] => New Vehicle [view_item] => View Vehicle [search_items] => Search Vehicles [not_found] => No Vehicles Found [not_found_in_trash] => No Vehicles found in Trash [parent_item_colon] => Operator [all_items] => Vehicles [menu_name] => Vehicles [name_admin_bar] => Vehicle ) [description] => Each vehicle is linked to an Operator [publicly_queryable] => 1 [exclude_from_search] => [capability_type] => post [map_meta_cap] => 1 [_builtin] => [_edit_link] => post.php?post=%d [hierarchical] => 1 [public] => 1 [rewrite] => Array ( [slug] => vehicle [with_front] => 1 [pages] => 1 [feeds] => 1 [ep_mask] => 1 ) [has_archive] => 1 [query_var] => [register_meta_box_cb] => [taxonomies] => Array ( [0] => category [1] => features [2] => colours [3] => drivers ) [show_ui] => 1 [menu_position] => [menu_icon] => [can_export] => 1 [show_in_nav_menus] => 1 [show_in_menu] => 1 [show_in_admin_bar] => 1 [delete_with_user] => [cctm_hierarchical_custom] => 1 [cctm_hierarchical_includes_drafts] => [cctm_hierarchical_post_types] => Array ( [0] => operator ) [cctm_custom_columns_enabled] => 0 [post_type] => vehicle [use_default_menu_icon] => 1 [label] => Vehicles [cctm_show_in_menu] => 1 [cctm_show_in_menu_custom] => [rewrite_with_front] => 1 [permalink_action] => /%postname%/ [rewrite_slug] => [include_in_search] => 1 [include_in_rss] => 1 [cctm_enable_right_now] => 1 [custom_order] => ASC [is_active] => 1 [custom_fields] => Array ( [0] => passenger_capacity [1] => luggage_capacity [2] => hourly_rate [3] => included_milleage [4] => additional_mileage_price [5] => additional_image ) [map_field_metabox] => Array ( [passenger_capacity] => cctm_vehicledetails [luggage_capacity] => cctm_vehicledetails [hourly_rate] => cctm_vehicledetails [included_milleage] => cctm_vehicledetails [additional_mileage_price] => cctm_vehicledetails [additional_image] => cctm_default ) [original_post_type_name] => vehicle [name] => vehicle [cap] => stdClass Object ( [edit_post] => edit_post [read_post] => read_post [delete_post] => delete_post [edit_posts] => edit_posts [edit_others_posts] => edit_others_posts [publish_posts] => publish_posts [read_private_posts] => read_private_posts [read] => read [delete_posts] => delete_posts [delete_private_posts] => delete_private_posts [delete_published_posts] => delete_published_posts [delete_others_posts] => delete_others_posts [edit_private_posts] => edit_private_posts [edit_published_posts] => edit_published_posts [create_posts] => edit_posts ) )  Update 2 archive-vehicle.php: <?php /** * The template for displaying Archive pages. * * Used to display archive-type pages if nothing more specific matches a query. * For example, puts together date-based pages if no date.php file exists. * * Learn more: http://codex.wordpress.org/Template_Hierarchy * * @package WordPress * @subpackage Twenty_Ten * @since Twenty Ten 1.0 */ get_header(); ?> <div class="container"> <div class="row"> <div class="col-md-8"> <div id="content" role="main"> <?php /* Queue the first post, that way we know * what date we're dealing with (if that is the case). * * We reset this later so we can run the loop * properly with a call to rewind_posts(). */ if ( have_posts() ) the_post(); ?> <h1 class="page-title"> <?php if ( is_day() ) : ?> <?php printf( __( 'Daily Archives: <span>%s</span>', 'twentyten' ), get_the_date() ); ?> <?php elseif ( is_month() ) : ?> <?php printf( __( 'Monthly Archives: <span>%s</span>', 'twentyten' ), get_the_date( _x( 'F Y', 'monthly archives date format', 'twentyten' ) ) ); ?> <?php elseif ( is_year() ) : ?> <?php printf( __( 'Yearly Archives: <span>%s</span>', 'twentyten' ), get_the_date( _x( 'Y', 'yearly archives date format', 'twentyten' ) ) ); ?> <?php else : ?> <?php _e( 'Blog Archives', 'twentyten' ); ?> <?php endif; ?> </h1> <?php /* Since we called the_post() above, we need to * rewind the loop back to the beginning that way * we can run the loop properly, in full. */ rewind_posts(); /* Run the loop for the archives page to output the posts. * If you want to overload this in a child theme then include a file * called loop-archive.php and that will be used instead. */ get_template_part( 'loop', 'archive' ); ?> </div><!-- #content --> </div><!-- .col-md-8 --> <div class="col-md-3 col-md-offset-1"> <?php get_sidebar(); ?> </div><!-- .col-md-3 --> </div><!-- .row --> </div><!-- .container --> <?php get_footer(); ?>  Update 3 wp-content\plugins\custom-content-type-manager\controllers\create_post_type.php: <?php /*------------------------------------------------------------------------------ Create a new post type. ------------------------------------------------------------------------------*/ if ( ! defined('CCTM_PATH')) exit('No direct script access allowed'); if (!current_user_can('administrator')) exit('Admins only.'); require_once(CCTM_PATH.'/includes/CCTM_PostTypeDef.php');$data=array();
$data['page_title'] = __('Create Custom Content Type', CCTM_TXTDOMAIN);$data['help'] = 'http://code.google.com/p/wordpress-custom-content-type-manager/wiki/CreatePostType';
$data['msg'] = '';$data['menu'] = sprintf('<a href="'.get_admin_url(false,'admin.php').'?page=cctm" title="%s" class="button">%s</a>', __('Cancel'), __('Cancel'));
$data['edit_warning'] = ''; // only used when you edit a post_type, not delete. // Variables for our template$fields   = '';

$data['action_name'] = 'custom_content_type_mgr_create_new_content_type';$data['nonce_name']  = 'custom_content_type_mgr_create_new_content_type_nonce';
$data['submit'] = __('Create New Content Type', CCTM_TXTDOMAIN);$data['action'] = 'create';

$data['post_type'] = ''; // as default$data['def'] = self::$default_post_type_def; //$def = self::$post_type_form_definition; // Save data if it was properly submitted if ( !empty($_POST) && check_admin_referer($data['action_name'],$data['nonce_name']) ) {
$sanitized_vals = CCTM_PostTypeDef::sanitize_post_type_def($_POST);
$error_msg = CCTM_PostTypeDef::post_type_name_has_errors($sanitized_vals, true);

if ( empty($error_msg) ) { // Clean slate. This nukes any instance of 'is_foreign' (and potentially other issues) // that may arise if the post-type name was used by another plugin and the CCTM tracked // custom fields for that plugin, and then later the other plugin was deactivated and // the CCTM wants to use the same post-type name. unset(CCTM::$data['post_type_defs'][ $sanitized_vals['post_type'] ]); CCTM_PostTypeDef::save_post_type_settings($sanitized_vals);

$data['msg'] = CCTM::format_msg( sprintf(__('The content type %s has been created', CCTM_TXTDOMAIN), '<em>'.$sanitized_vals['post_type'].'</em>'));
self::set_flash($data['msg']); include CCTM_PATH . '/controllers/list_post_types.php'; return; } else { // clean up... menu labels in particular can get gunked up. :($data['def']  = $sanitized_vals;$data['def']['labels']['singular_name'] = '';
$data['def']['label'] = '';$data['msg'] = CCTM::format_error_msg($error_msg); } }$data['icons'] = CCTM_PostTypeDef::get_post_type_icons();
$data['columns'] = CCTM_PostTypeDef::get_columns($post_type);
$data['orderby_options'] = CCTM_PostTypeDef::get_orderby_options($post_type);
$data['content'] = CCTM::load_view('post_type.php',$data);
print CCTM::load_view('templates/default.php', $data); /*EOF*/  wp-content\plugins\custom-content-type-manager\includes\CCTM.php register_custom_post_types function: public static function register_custom_post_types() { //return;$post_type_defs = self::get_post_type_defs();

foreach ($post_type_defs as$post_type => $def) {$def = self::_prepare_post_type_def($def); if ( isset($def['is_active'])
&& !empty($def['is_active']) && !in_array($post_type, self::$built_in_post_types) && isset($def['post_type'])
) {
register_post_type( $post_type,$def );
}
}
// Added per issue 50
global $wp_rewrite;$wp_rewrite->flush_rules();
}
}

-
Can you provide us the code where it generates error on line 439. It seems in_array() parameter 2 is not an array. Actually in_array require 2nd parameter to be an array. –  Rahil Wazir Sep 25 '13 at 12:22
@RahilWazir I've added line 439 as suggested - I should point out that nav-menu-template.php is a WP core file –  gpcola Sep 25 '13 at 12:34
@gpcola You're using the PHP function in_array() which only works for checking if a string exists in an ARRAY. You are attempting to check if your string exists in an OBJECT, using the in_array() PHP function. That is why you are receiving that error. Parameter 2 of in_array() must be an ARRAY. –  Michael Ecklund Sep 25 '13 at 12:45
Post of the contents of your archive-vehicle.php. Specifically any parts what call wp_nav_menu or related functions. –  chrisguitarguy Sep 25 '13 at 12:51
@MichaelEcklund - nav-menu-template.php is a WP core file so I have no control over it. –  gpcola Sep 25 '13 at 12:56
show 1 more comment

print_r($queried_object) right before line 439 generates the following - there's no 'ancestors' key: When you are on a post type archive calling get_queried_object (which the code probably does) or using WP_Query::$queried_object return the post type "object". All that is is the arguments with which the post type was registered.

The relevant bit of nav-menu-template.php in WordPress 3.6.

<?php
function _wp_menu_item_classes_by_context( &$menu_items ) { // ... foreach ( (array)$menu_items as $key =>$parent_item ) {
// ...
if (
isset( $parent_item->type ) && ( // ancestral post object ( 'post_type' ==$parent_item->type &&
! empty( $queried_object->post_type ) && is_post_type_hierarchical($queried_object->post_type ) &&
in_array( $parent_item->object_id,$queried_object->ancestors ) &&
$parent_item->object !=$queried_object->ID
) ||

// ancestral term
(
'taxonomy' == $parent_item->type && isset($possible_taxonomy_ancestors[ $parent_item->object ] ) && in_array($parent_item->object_id, $possible_taxonomy_ancestors[$parent_item->object ] ) &&
(
! isset( $queried_object->term_id ) ||$parent_item->object_id != $queried_object->term_id ) ) ) ) {$classes[] = empty( $queried_object->taxonomy ) ? 'current-' .$queried_object->post_type . '-ancestor' : 'current-' . $queried_object->taxonomy . '-ancestor'; } // ... } // ... }  This bit ! empty($queried_object->post_type ) should evaluate to false on post type archives. Something is adding post type to the queried object. And by something I mean your plugin which is _doing_it_wrong. Take a look at CCTM::register_custom_post_types() and CCTM::$default_post_type_def. Anything that get's passed into register_post_type is just stored as an argument in the post type globals array. If I do this: register_post_type('some_type', array('this_is_not_a_wp_arg' => true));  On archive-some_type.php I can check for this_is_not_a_wp_arg. <?php // archive-some_type.php var_dump(get_queried_object()->this_is_not_a_wp_arg); // true  Because your plugin happens to put post_type into the arguments array, it causes WP to evaluate ! empty($queried_object->post_type ) as true. This isn't an issue in archive.php because $query_object->post_type is empty. As it should be on any post type archive. Unfortunately the CCTM plugin author doesn't understand the consequences of passing a "reserved" word like post_type as an argument key. This is why prefixing things is important. EDIT A very hackish fix is to hook into init very late and loop through all the post types. If the post_type argument is set, remove it. This may break other things the plugin does in the admin area. <?php add_action('init', 'wpse115604_fix', 10000); function wpse115604_fix() { foreach (get_post_types(array(), 'objects') as$type) {
if (isset($type->post_type)) { unset($type->post_type);
}
}
}


This would prevent you from having to edit the plugin itself. I would do the above, then report the issue to the plugin author. If/when it gets fixed in a future version, you'll be able to remove that code.

TL;DR: CCTM adds a key to registered post types named post_type is messes with the order of things and sets a sequence of errors in motion.

-
Chris I've added the contents of wp-content\plugins\custom-content-type-manager\controllers\create_post_type.php above - note line 25 which reads $data['post_type'] = ''; // as default - isn't that suggesting that the $queried_object->post_type ought to be empty? –  gpcola Sep 25 '13 at 13:44
I also dug out the register_custom_post_types() function from wp-content\plugins\custom-content-type-manager\includes\CCTM.php –  gpcola Sep 25 '13 at 14:02
Assuming this problem relates to the fact that post_type exists in the arguments array - how should I remove that key? If I edit create_post_type.php and comment out line 25 that would stop it from being added in future but what about my existing posts - how do I fix them? I hope I've understood what you said in your answer! –  gpcola Sep 25 '13 at 14:10
Gave you a possible solution in an edit just now. I would try to avoid editing the plugin itself. –  chrisguitarguy Sep 25 '13 at 14:20
Chris I really appreciate your efforts here - that hack worked in-so-much as I no longer see errors in the header. I will post on http://wordpress.org/support/forum/plugins-and-hacks, linking to this question and hopefully the CCTM author will get around to solving this in a future update... –  gpcola Sep 25 '13 at 14:28