[wp-trac] [WordPress Trac] #49332: method Walker_Nav_Menu::start_el should not call filter the_title on non post menu items
WordPress Trac
noreply at wordpress.org
Thu Jan 30 17:16:29 UTC 2020
#49332: method Walker_Nav_Menu::start_el should not call filter the_title on non
post menu items
--------------------------+-----------------------------
Reporter: erwinbr | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version: 5.3.2
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
I am working on a site with a.o:
- WP 5.3.2
- WPML 4.3.6
- Estatik-pro 3.8.1
- Divi 3.29.1
And am seeing the following notices in the debug log:
PHP Notice: Trying to get property 'post_type' of non-object in .\wp-
content\plugins\estatik-pro_3.8.1\functions.php on line 386
PHP Stack trace:
PHP 1. {main}() .\index.php:0
PHP 2. require() .\index.php:17
PHP 3. require_once() .\wp-blog-header.php:19
PHP 4. include() .\wp-includes\template-loader.php:98
PHP 5. get_header() .\wp-content\themes\Divi\single.php:3
PHP 6. locate_template() .\wp-includes\general-template.php:41
PHP 7. load_template() .\wp-includes\template.php:671
PHP 8. require_once() .\wp-includes\template.php:722
PHP 9. wp_nav_menu() .\wp-content\themes\Divi\header.php:263
PHP 10. walk_nav_menu_tree() .\wp-includes\nav-menu-template.php:217
PHP 11. Walker_Nav_Menu->walk() .\wp-includes\nav-menu-template.php:583
PHP 12. Walker_Nav_Menu->display_element() .\wp-includes\class-wp-
walker.php:244
PHP 13. Walker_Nav_Menu->display_element() .\wp-includes\class-wp-
walker.php:156
PHP 14. Walker_Nav_Menu->start_el() .\wp-includes\class-wp-walker.php:144
PHP 15. apply_filters() .\wp-includes\class-walker-nav-menu.php:213
PHP 16. WP_Hook->apply_filters() .\wp-includes\plugin.php:206
PHP 17. es_the_title_filter() .\wp-includes\class-wp-hook.php:288
(If you want, I can post a stack trace with variable info.)
Diving into this problem I noticed that:
- The main nav menu does not only contain items that are a post, but also
the language switcher flags (added by WPML)
- On line 213 of file wp-includes/class-walker-nav-menu.php,
Walker_Nav_Menu->start_el() calls
{{{
apply_filters( 'the_title', $item->title, $item->ID );
}}}
for all items in the menu, be it posts or other items.
- Estatik-pro hooks into this filter and calls get_post() on the given ID
which is not a post ID:
{{{#!php
<?php
function es_the_title_filter( $title, $id = null ) {
global $es_settings;
$post = get_post( $id );
if ( is_single() && $post->post_type ==
Es_Property::get_post_type_name() ) {
...
}
return $title;
}
add_filter( 'the_title', 'es_the_title_filter', 10, 2 );
}}}
Who is wrong?
- WPML: by adding non-posts to menu's.
- Estatik-pro for not checking that the filter is called for non-posts?
- Walker_Nav_Menu->start_el() for unconditionally calling the filter
'the_title' on all menu-items?
IMO:
- Menu-items can be other things than posts, and WPML shows that this is
indeed possible.
- The filter 'the_title' seems to be explicitly for altering a post title,
not titles of images, non-post menu-items, or whatever. So Estatik-pro
should not have to check that the given ID is indeed from a post.
- Walker_Nav_Menu->start_el() calls its own filter 'nav_menu_item_title'
directly after calling the 'the_title' filter (though still documenting
$item as a WP_Post).
Based on the above, my conclusion is: Walker_Nav_Menu->start_el() should
check if the item is a WP_Post before calling the 'the_title' filter.
If you agree, solving this should be easy, surround line 213 with
{{{
if ( $item instanceof WP_Post ) { ... }
}}}
However, in a lot of places it is documented that a menu-item is a WP_Post
and changing that may take considerably more work.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/49332>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list