0

I'm using a plugin where I have manipulated a function within a class of the plugin. However I would like to put this function in my theme instead since if someone updates the plugin, my edits to the function will be replaced. But if I lift out my edited function and put in the theme I get the error that "Fatal error: Cannot declare class Groups_Post_Access, because the name is already in use in ..."

The function within class Groups_Post_Access originally looks like this:

public static function wp_get_nav_menu_items( $items = null, $menu = null, $args = null ) {
    $result = array();
    if ( apply_filters( 'groups_post_access_wp_get_nav_menu_items_apply', true, $items, $menu, $args ) ) {
        $user_id = get_current_user_id();
        foreach ( $items as $item ) {
            // @todo might want to check $item->object and $item->type first,
            // for example these are 'page' and 'post_type' for a page
            if ( self::user_can_read_post( $item->object_id, $user_id ) ) {
                $result[] = $item;
            }
        }
    } else {
        $result = $items;
    }
    return $result;
}

And my version is like this:

public static function wp_get_nav_menu_items( $items = null, $menu = null, $args = null ) {
    $result = array();
    if ( apply_filters( 'groups_post_access_wp_get_nav_menu_items_apply', true, $items, $menu, $args ) ) {
        $user_id = get_current_user_id();
        foreach ( $items as $item ) {
            // @todo might want to check $item->object and $item->type first,
            // for example these are 'page' and 'post_type' for a page
            if ( self::user_can_read_post( $item->object_id, $user_id ) ) {
                $group_ids = self::get_read_group_ids( $item->object_id );
                if ( count( $group_ids ) > 0 ) {
                    $item->title .= '<i class="unlocked"></i>';
                }
                $result[] = $item;
            } else {
                $item->title .= '<i class="locked"></i>';
                $result[] = $item;
            }
        }
    } else {
        $result = $items;
    }
    return $result;
}

So is there a way to override the function, or disable the class somehow from my theme? So it keeps separate from all the plugins file and then don't get replaced by an update for an example.

  • Can you show the full code where the class is defined within the plugin? There might be some ways, but it is also possible that you simply cannot do what you want to do (this way). – kero May 29 at 10:11
  • You would need to add where this nav menu is being output and how to your question for a more complete answer. – majick May 31 at 4:04
0

You can extend the existing class to override a particular class method (function):

class Mod_Groups_Post_Access extends Groups_Post_Access {
    public static function wp_get_nav_menu_items( $items = null, $menu = null, $args = null ) {
    // ... your code ...
   }
}

Then you would need to call $instance = new Mod_Groups_Post_Access(); instead of $instance = new Groups_Post_Access(); so you can use the modified function/method via:

$instance->wp_get_nav_menu_items();

You can read up further on object inheritance here: https://www.php.net/manual/en/language.oop5.inheritance.php

  • That's only useful if they even have the opportunity to instantiate the class. If the original theme is still instantiating the original class you'll get conflicts. – Jacob Peattie May 29 at 15:33
  • Sure, but looks from the code it is just used to output a nav menu slightly differently. So in this case the alternative class may be able to be called in a modified theme template / plugin filter / shortcode. That context is missing from the question so will ask. – majick May 31 at 4:03
0

So my solution was to use remove_filter and add_filter

In my theme's functions.php file I managed to override the custom get_nav function like this:

remove_filter( 'wp_get_nav_menu_items', array( Groups_Post_Access::class, 'wp_get_nav_menu_items' ), 1, 3 );

add_filter( 'wp_get_nav_menu_items', 'my_custom_get_nav_menu_items', 10, 3 );

function my_custom_get_nav_menu_items( $items = null, $menu = null, $args = null ) {
    $result = array();
        $user_id = get_current_user_id();
        foreach ( $items as $item ) {
                if ( Groups_Post_Access::user_can_read_post( $item->object_id, $user_id ) ) {
                        $group_ids = Groups_Post_Access::get_read_group_ids( $item->object_id );
                        if ( count( $group_ids ) > 0 ) {
                                $item->title .= '<i class="unlocked"></i>';
                        }
                        $result[] = $item;
                } else {
                        $item->title .= '<i class="locked"></i>';
                        $result[] = $item;
                }
        }

    return $result;
}

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.