Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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
    // http://code.google.com/p/wordpress-custom-content-type-manager/issues/detail?id=50
    if (self::get_setting('flush_permalink_rules')){
        global $wp_rewrite;
        $wp_rewrite->flush_rules();     
    }
}
share|improve this question
    
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

1 Answer

up vote 0 down vote accepted

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.

share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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