Release Notes

  • Fixed issue with unavailable inbox for admins (reported by Lee)
  • Fixed permission caching bug
  • @mrcoffee I pulled up a vanilla Elgg 1.8.3 installation, added "login_as", "roles", "roles_moderators" plugins, did everything as you said, and I still don't get the error. It must be some unexpected interference with another 3rd party plugin. What Elgg version are you using? What other plugins do you have enabled at your site?

  • Hiya Andras - I seem to have lost the ability to define the default member, admin and visitor roles somewhere along the line (I've been experimenting a lot!)... I know it isn't my role plugin as on another installation it works fine and I can set default roles... do you have any idea how I may go about getting them back?

    Thanks

    Nick

  • Hi,

    I Found some bug or maybe i implemented it wrong.

    i'm trying to add more than one menu item for a specific role but it always adding the last one, i defined.

    here is my code.

    'menus' => array(

                        'topbar::administration' => array('rule' => 'deny'),
                       
                        'site::blog' => array('rule' => 'deny')    ,
                       
                        'site::activity' => array('rule' => 'deny')    ,
                       
                   
                        'site' => array(
                            'rule' => 'extend',
                            'menu_item' => array(
                                'name' => 'votes',
                                'text' => 'votes',
                                'href' => '/content/votes'
                            )
                        ),
                        'site' => array(
                            'rule' => 'extend',
                            'menu_item' => array(
                                'name' => 'results',
                                'text' => 'results',
                                'href' => '/content/results'
                            )
                        ),
                        'site' => array(
                            'rule' => 'extend',
                            'menu_item' => array(
                                'name' => 'feeds',
                                'text' => 'feeds',
                                'href' => '/content/feeds'
                            )
                        )
                   
                    ),

     

    Please advice.

     

    Thanks,

    Shachar

  • @Shachar this is actually a bug, thanks for reporting. Instead of

    'site' => array(...),

    'site' => array(...),

     

    definitions, use

    'site::votes' => array(...),

    'site::results' => array(...),

     

    type of definitions - they keys for each rules section (i.e. menus, views, actions, etc.) need to be unique within a given role. Additionally, you'll need to apply the fix I outlined in this thread for Nick Scott (see previous page), then finally change one line of code: around line 212, replace

    elgg_register_menu_item($menu, $menu_obj);

    with

    elgg_register_menu_item($menu_name, $menu_obj);

     

    Sorry for the inconvenience. I'll try to upload a new version as soon as I get to it.


  • @Andras Many thanks for the reply the fix worked!

    only one thing how can i control the order of the items, somehow he put my first item as last, but when i put it last it is first.

    any clue how to fix it?

    Thanks,

    Shachar

  • @Andras

    I have a problem with the role framework plugin, that it is not recognizing user different language.

    Can you please assist?

    i'll apreciate quick response

  • hey thanks! after adding a Semicolon..i get a new error.


    Fatal error: Call to a member function getName() on a non-object in /home/mrcoffee/public_html/mod/roles/lib/roles.php on line 394

    mm. i hope this helps debug, and make this awesome plugin useable for others!

  • I'm getting the fatal error mentioned above as well.  However, it's only when the Group Administrators for Roles is enabled.  I can enable roles and Moderators for Roles all day long and it's fine.  However, as soon as I enable Group Administrators for Roles one user reports the problem when he visits the Groups page.

    Here is the kicker.  When I sign into the site using the user account that reported the problem it works fine.  When he signs in from his location it errors out.  We're both using the same operating system and web browser.

  • Oh, I forgot to mention that it's also happening on more than one computer at the user's location.

  • @everyone thanks for the reports, I'll try to have a look at this issue until the end of the week. My problem is that despite all efforts I still did not manage to reproduce it in my environments. Nonetheless I'll just try to make that part of the code more robust, hopefully that will help.

  • I just had the same user try with a new user account and he received the same error.  However, from my location both of his accounts work fine so I, too, am unable to reproduce the problem.

  • @Andras

    Thanks for the reply.

    I fixed my current problem by adding a new role with differrent labels, and assign the user with specific language to this role. but i think it is kind of a hack. anyway wanted to share if someone else have similar problem.

     

  • Hi Andras,

    I think I found the bug for 

    Fatal error: Call to a member function getName() on a non-object in/home/mrcoffee/public_html/mod/roles/lib/roles.php on line 394

     

    It is in the theme that is used, trying to get rid of the Elgg logo, fx. bright theme:

     

    function bright_theme_init() {

      elgg_unregister_menu_item('topbar', 'elgg_logo');

    }

    @elgg_unregister_menu_item is used in the file engine/lib/navigation.php in line 117.

    This function has the variable $item_name, and $item_name is used in the foreach, where getName appears.

    foreach ($CONFIG->menus[$menu_name] as $index => $menu_object) {

    if ($menu_object->getName() == $item_name) {

    unset($CONFIG->menus[$menu_name][$index]);

    return true;

    }

    }

    and getName is used in your line 394 in the roles.php file.

    if (is_array($menu)) {

    $count = count($menu);

    while(!$found && (++$index < $count)) {

    if ($menu[$index]->getName() === $item_name) {

    $found = true;

    }

    }

    }

    Could this be the explanation?

     

  • @muller: try this little debug (code in bold below) in roles.php -- the dbg will stop the script after the displays - can delete the debug code afterwards. post back here - what displays ?

    // and getName is used in your line 394 in the roles.php file.
    if(is_array($menu))
    {
        $count = count($menu);
        while(!$found && (++$index < $count))
        {
            // :DC: (START DBG)
            echo"<h2>(START DBG)</h2>";
            echo"<h2>(DUMP MENU @ $index of ,max=$count ? )</h2>";
            print_r($menu[$index]);
            echo"<h2>(END DBG)</h2>";
            exit();
            // :DC: (END DBG)
            if($menu[$index]->getName() === $item_name)
            {
                $found = true;

     

     

  • The debug says:

    (START DBG)

    (DUMP MENU @ 0 of ,max=6 ? )

    (END DBG)

  • This when trying to login as a moderator, after given the role. When logged in, white page and the debug message.

  • 'something' is messed up in that menu table at first row...

    TRY

        while(!$found && (++$index < $count))
        {
            // :DC: (START DBG)
            echo"<h2>(START DBG) ITEM_NAME= ($item_name)</h2>";
            echo"<h2>(DUMP MENU @ $index of max=$count ? )</h2>";
            echo"<hr>TRY DUMP MENU[]:=";// what is current menu item content?
            print_r($menu[$index]);
            echo"<hr>END - TRY DUMP MENU[]";
            if(is_object($menu[$index]))//is menu item an object?
                echo"<hr><h2>IS OBJECT ? YES</h2>";
            else
                echo"<hr><h2>IS OBJECT ? ERROR</h2>";
            echo"<h2>(END DBG)</h2>";
            exit();
            // :DC: (END DBG)
            if($menu[$index]->getName() === $item_name)
    ...

     

  • in an attempt to be helpfull..

    <?php

    /**
     *
     * Roles library functions
     *
     * @package Roles
     * @author Andras Szepeshazi
     * @copyright Arck Interactive, LLC 2012
     * @link http://www.arckinteractive.com/
     */

    /**
     * Obtains the role of a given user
     *
     * @param ElggUser $user

     * @return ElggRole The role the user belongs to
     */
    function roles_get_role($user = null) {

        $user = $user ? $user : elgg_get_logged_in_user_entity();

        if (elgg_instanceof($user, 'user')) {
            $options = array(
                'type' => 'object',
                'subtype' => 'role',
                'relationship' => 'has_role',
                'relationship_guid' => $user->guid,
            );
            $roles = elgg_get_entities_from_relationship($options);

            if (is_array($roles) && !empty($roles)) {
                return $roles[0];
            }
        }

        // Couldn't find role for the current user, or there is no logged in user
        return roles_get_role_by_name(roles_filter_role_name(NO_ROLE));
    }

    /**
     * Checks if the user has a specific role
     *
     * @param ElggUser $user

     * @return bool True if the user belongs to the passed role, false otherwise
     */
    function roles_has_role($user = null, $role_name = DEFAULT_ROLE) {

        $user = $user ? $user : elgg_get_logged_in_user_entity();
        if (!elgg_instanceof($user, 'user')) {
            return false;
        }

        $options = array(
            'type' => 'object',
            'subtype' => 'role',
            'metadata_name_value_pairs' => array('name' => 'name', 'value' => $role_name, 'operand' => '='),
            'relationship' => 'has_role',
            'relationship_guid' => $user->guid,
        );
        $roles = elgg_get_entities_from_relationship($options);


        if (is_array($roles) && !empty($roles)) {
            return true;
        }
        return false;
    }

    /**
     * Assigns a role to a particular user
     *
     * @param ElggRole $role The role to be assigned
     * @param ElggUser $user The user the role needs to be assigned to

     * @return mixed True if the role change was successful, false if could not update user role, and null if there was no change in user role
     */

    function roles_set_role($role, $user = null) {
        if (!elgg_instanceof($role, 'object', 'role')) {
            return false;    // Couldn't set new role
        }

        $user = $user ? $user : elgg_get_logged_in_user_entity();
        if (!elgg_instanceof($user, 'user')) {
            return false;    // Couldn't set new role
        }

        $current_role = roles_get_role($user);
        if ($role != $current_role) {
            remove_entity_relationships($user->guid, 'has_role');
            if (($role->name != DEFAULT_ROLE) && ($role->name != ADMIN_ROLE)) {
                if (!add_entity_relationship($user->guid, 'has_role', $role->guid)) {
                    return false;    // Couldn't set new role
                }
            }
            return true; // Role has been changed
        }

        return null; // There was no change necessary, old and new role are the same
    }

    /**
     * Gets all role objects
     *
     * @return mixed An array of ElggRole objects defined in the system, or false if none found
     */

    function roles_get_all_roles() {

        $options = array(
            'type' => 'object',
            'subtype' => 'role',
            'limit' => 0

        );
        return elgg_get_entities($options);

    }

    /**
     *
     * Gets all non-default role objects
     * This is used by the role selector view. Default roles (VISITOR_ROLE, ADMIN_ROLE, DEFAULT_ROLE) need to be omitted from
     * the list of selectable roles - as default roles are automatically assigned to users based on their Elgg membership type
     *
     * @return mixed An array of non-default ElggRole objects defined in the system, or false if none found
     */
    function roles_get_all_selectable_roles() {

        $dbprefix = elgg_get_config('dbprefix');
        $reserved_role_names = "('" . implode("','", ElggRole::getReservedRoleNames()) ."')";
        $options = array(
            'type' => 'object',
            'subtype' => 'role',
            'limit' => 0,
            'joins' => array(
                "INNER JOIN {$dbprefix}metadata m ON (m.entity_guid = e.guid)",
                "INNER JOIN {$dbprefix}metastrings s1 ON (s1.id = m.name_id AND s1.string = 'name')",
                "INNER JOIN {$dbprefix}metastrings s2 ON (s2.id = m.value_id)",
            ),
            'wheres' => array("s2.string NOT IN $reserved_role_names")
        );
        return elgg_get_entities($options);
    }

    /**
     * Obtains a list of permissions associated with a particular role object
     *
     * @global array $PERMISSIONS_CACHE In-memory cache for role permission
     * @param ElggRole $role The role to check for permissions
     * @param string $permission_type The section from the configuration array ('actions', 'menus', 'views', etc.)
     *
     * @return array The permission rules for the given role and permission type
     */

    function roles_get_role_permissions($role = null, $permission_type = null) {
        global $PERMISSIONS_CACHE;

        $role = ($role == null) ? roles_get_role() : $role;
        if (!elgg_instanceof($role, 'object', 'role')) {
            return false;
        }

        if (!isset($PERMISSIONS_CACHE[$role->name])) {
            roles_cache_permissions($role);
        }

        if ($permission_type) {
            return $PERMISSIONS_CACHE[$role->name][$permission_type];
        } else {
            return $PERMISSIONS_CACHE[$role->name];
        }

    }

    /**
     * Caches permissions associated with a role object. Also resolves all role extensions.
     *
     * @global array $PERMISSIONS_CACHE In-memory cache for role permission
     * @param ElggRole $role The role to cache permissions for
     */

    function roles_cache_permissions($role) {
        global $PERMISSIONS_CACHE;
        if (!is_array($PERMISSIONS_CACHE[$role->name])) {
            $PERMISSIONS_CACHE[$role->name] = array();
        }

        // Let' start by processing role extensions
        $extends = $role->extends;
        if (!empty($role->extends) && !is_array($extends)) {
            $extends = array($extends);
        }
        if (is_array($extends) &&  !empty($extends)) {
            foreach ($extends as $extended_role_name) {

                $extended_role = roles_get_role_by_name($extended_role_name);
                if (!isset($PERMISSIONS_CACHE[$extended_role->name])) {
                    roles_cache_permissions($extended_role);
                }

                foreach ($PERMISSIONS_CACHE[$extended_role->name] as $type => $permission_rules) {
                    if (is_array($PERMISSIONS_CACHE[$role->name][$type])) {
                        $PERMISSIONS_CACHE[$role->name][$type] = array_merge($PERMISSIONS_CACHE[$role->name][$type], $permission_rules);
                    } else {
                        $PERMISSIONS_CACHE[$role->name][$type] = $permission_rules;
                    }
                }
            }
        }

        $permissions = unserialize($role->permissions);
        foreach ($permissions as $type => $permission_rules) {
            if (is_array($PERMISSIONS_CACHE[$role->name][$type])) {
                $PERMISSIONS_CACHE[$role->name][$type] = array_merge($PERMISSIONS_CACHE[$role->name][$type], $permission_rules);
            } else {
                $PERMISSIONS_CACHE[$role->name][$type] = $permission_rules;
            }
        }

    }

    /**
     * Gets a role object based on it's name
     *
     * @param string $role_name The name of the role

     * @return mixed An ElggRole object if it could be found based on the name, false otherwise
     */

    function roles_get_role_by_name($role_name) {
        $options = array(
            'type' => 'object',
            'subtype' => 'role',
            'metadata_name_value_pairs' => array('name' => 'name', 'value' => $role_name, 'operand' => '=')
        );
        $role_array = elgg_get_entities_from_metadata($options);

        if (is_array($role_array) && !empty($role_array)) {
            return $role_array[0];
        } else {
            return false;
        }

    }

    /**
     * Resolves the default role for the currently logged in user

     * @param string $role_name The name uf the user's role
     */
    function roles_filter_role_name($role_name) {
        if ($role_name !== NO_ROLE) {
            return $role_name;
        }

        if (!elgg_is_logged_in()) {
            return VISITOR_ROLE;
        } else if (elgg_is_admin_logged_in()) {
            return ADMIN_ROLE;
        } else {
            return DEFAULT_ROLE;
        }
    }

    /**
     * Processes the configuration files and generates the appropriate ElggRole objects.
     *
     * If, for any role definition, there is an already existing role with the same name,
     * the role permissions will be updated for the given role object.
     * If there is no previously existing, corresponding role object, it will be created now.
     *
     * @param array $roles_array The roles configuration array
     */

    function roles_create_from_config($roles_array) {

        $options = array(
                'type' => 'object',
                'subtype' => 'role',
        );
        $roles = elgg_get_entities($options);

        $existing_roles = array();
        foreach ($roles as $role) {
            $existing_roles[$role->name] = $role;
        }

        foreach($roles_array as $rname => $rdetails) {
            $current_role = $existing_roles[$rname];
            if (elgg_instanceof($current_role, 'object', 'role')) {
                // Update existing role obejct
                $current_role->title = elgg_echo($rdetails['title']);
                $current_role->extends = $rdetails['extends'];
                $current_role->permissions = serialize($rdetails['permissions']);
                $current_role->save();
            } else {
                // Create new role object
                $new_role = new ElggRole();
                $new_role->title = elgg_echo($rdetails['title']);
                $new_role->owner_guid = elgg_get_logged_in_user_guid();
                $new_role->container_guid = $new_role->owner_guid;
                $new_role->access_id = ACCESS_PUBLIC;
                if (!($new_role->save())) {
                    error_log('Could not create new role $rname');
                } else {
                    // Add metadata
                    $new_role->name = $rname;
                    $new_role->extends = $rdetails['extends'];
                    $new_role->permissions = serialize($rdetails['permissions']);
                }
            }
        }

    }

    /**
     * Checks if the configuration array has been updated and updates role objects accordingly if needed
     *
     */
    function roles_check_update() {
        $hash = elgg_get_plugin_setting('roles_hash', 'roles');
        $roles_array = elgg_trigger_plugin_hook('roles:config', 'role', array(), null);

        $current_hash = sha1(serialize($roles_array));

        if ($hash != $current_hash) {
            roles_create_from_config($roles_array);
            elgg_set_plugin_setting('roles_hash', $current_hash, 'roles');
        }
    }


    /**
     *
     * Unregisters a menu item from the passed menu array.
     * Safe to use with dynamically created menus (as response to the "prepare", "menu" hook).
     *
     * @param array $menu The menu array
     * @param string $item_name The menu item's name ('blog', 'bookmarks', etc.) to be removed
     *
     * @return array The new menu array without the unregistered item
     */
    function roles_unregister_menu_item($menu, $item_name) {
        $updated_menu = $menu;

        if (false !== $index = roles_find_menu_index($updated_menu, $item_name)) {
            array_splice($updated_menu, $index, 1);
        }
       
        return $updated_menu;
    }

    /**
     *
     * Replaces an existing menu item with a new one.
     * Safe to use with dynamically created menus (as response to the "prepare", "menu" hook).
     *
     * @param array $menu The menu array
     * @param string $item_name The menu item's name ('blog', 'bookmarks', etc.) to be replaced
     * @param ElggMenuItem $menu_obj The replacement menu item
     *
     * @return array The new menu array with the replaced item
     */
    function roles_replace_menu_item($menu, $item_name, $menu_obj) {
        $updated_menu = $menu;
       
        if (false !== $index = roles_find_menu_index($updated_menu, $item_name)) {
            array_splice($updated_menu, $index, 1, array($menu_obj));
        }
       
        return $updated_menu;
    }

    /**
     *
     * Finds the index of a menu item in the menu array
     *
     * @param string $menu The menu array
     * @param string $item_name The menu item's name ('blog', 'ookmarks', etc.) to be replaced
     *
     * @return int The index of the menu item in the menu array
     */
    function roles_find_menu_index($menu, $item_name) {
        $index = -1;
        $found = false;

        if (is_array($menu)) {
            $count = count($menu);
            while(!$found && (++$index < $count))
        {
            // :DC: (START DBG)
            echo"<h2>(START DBG) ITEM_NAME= ($item_name)</h2>";
            echo"<h2>(DUMP MENU @ $index of max=$count ? )</h2>";
            echo"<hr>TRY DUMP MENU[]:=";// what is current menu item content?
            print_r($menu[$index]);
            echo"<hr>END - TRY DUMP MENU[]";
            if(is_object($menu[$index]))//is menu item an object?
                echo"<hr><h2>IS OBJECT ? YES</h2>";
            else
                echo"<hr><h2>IS OBJECT ? ERROR</h2>";
            echo"<h2>(END DBG)</h2>";
            exit();
            // :DC: (END DBG)
            if($menu[$index]->getName() === $item_name) {
                if ($menu[$index]->getName() === $item_name) {
                    $found = true;
                }
            }
        }
        return $found ? $index : false;
    }


    /**
     *
     * Substitutes dynamic parts of a menu's target URL
     *
     * @param array $vars An associative array holding the menu permissions
     *
     * @return The substituted menu permission array
     */
    function roles_prepare_menu_vars($vars) {

        $prepared_vars = $vars;
        if (isset($prepared_vars['href'])) {
            $prepared_vars['href'] = roles_replace_dynamic_paths($prepared_vars['href']);
        }

        return $prepared_vars;
    }


    /**
     *
     * Gets a menu by name
     *
     * @param string $menu_name The name of the menu
     *
     * @return array The array of ElggMenuItem objects from the menu
     */
    function roles_get_menu($menu_name) {
        global $CONFIG;
        return $CONFIG->menus[$menu_name];
    }

    /**
     *
     * Replaces certain parts of path and URL type definitions with dynamic values
     *
     * @param string $str The string to operate on
     *
     * @return string The updated, substituted string
     */
    function roles_replace_dynamic_paths($str) {
        $user = elgg_get_logged_in_user_entity();
        if (elgg_instanceof($user, 'user')) {
            $self_username = $user->username;
            $self_guid = $user->guid;
            $role = roles_get_role($user);

            $res = str_replace('{$self_username}', $self_username, $str);
            $res = str_replace('{$self_guid}', $self_guid, $res);
            if (elgg_instanceof($role, 'object', 'role')) {
                $res = str_replace('{$self_rolename}', $role->name, $res);
            }
        }
       
        // Safe way to get hold of the page owner before system, ready event
        $pageowner_guid = elgg_trigger_plugin_hook('page_owner', 'system', NULL, 0);
        $pageowner = get_entity($pageowner_guid);
       
        if (elgg_instanceof($pageowner, 'user')) {
            $pageowner_username = $pageowner->username;
            $pageowner_role = roles_get_role($pageowner);

            $res = str_replace('{$pageowner_name}', $pageowner_username, $res);
            $res = str_replace('{$pageowner_guid}', $pageowner_guid, $res);
            $res = str_replace('{$pageowner_rolename}', $pageowner_role->name, $res);
        }

        return $res;
    }


    /**
     *
     * Checks if a path or URL type rule matches a given path. Also processes regular expressions
     *
     * @param string $rule The permission rule to check
     * @param string $path The path to match against
     *
     * @return boolean True if the rule matches the path, false otherwise
     */
    function roles_path_match($rule, $path) {
        if (preg_match('/^regexp\((.+)\)$/', $rule) > 0) {
            // The rule contains regular expression; use regexp matching for the current path
            $pattern = preg_replace('/^regexp\(/', '', $rule);
            $pattern = preg_replace('/\)$/', '', $pattern);
            return preg_match($pattern, $path);
        } else {
            // The rule contains a simple string; default string comparision will be used
            return ($rule == $path);
        }
    }

    /**
     *
     * Checks if a permission rule should be executed for the current context
     *
     * @param string $permission_details The permission rule configuration
     * @param boolean $strict    If strict context matching should be used.
     *                             If true, only the last context will be checked for the rule matching.
     *                             If false, any context value in the context stack will be considered.
     *
     * @return True if the rule should be executed, false otherwise
     */
    function roles_check_context($permission_details, $strict = false) {
        global $CONFIG;
        $result = true;
        if (is_array($permission_details['context'])) {
            if ($strict) {
                $result = in_array(elgg_get_context(), $permission_details['context']);
            } else {
                $result = count(array_intersect($permission_details['context'], $CONFIG->context)) > 0;
            }
        }
        return $result;
    }

    /**
     *
     * Updates roles objects to 1.0.1 version
     */
    function roles_update_100_to_101() {

        // Remove all 'roles_hash' values from plugin settings
        // This will force new storage of the configuration array hash
        $dbprefix = elgg_get_config('dbprefix');
        $statement = "DELETE from {$dbprefix}private_settings WHERE name = 'roles_hash'";
        return delete_data($statement);
    }

    ?>

    site crashed. good thing i saved. :D reverted to default.

  • Debug says:

    (START DBG)

    (DUMP MENU @ 0 of ,max=22 ? )

    ElggMenuItem Object ( [data:protected] => Array ( [name] => dashboard [contexts] => Array ( [0] => admin ) [section] => administer [priority] => 10 [selected] => [parent_name] => [parent] => [children] => Array ( ) [itemClass] => Array ( ) [linkClass] => Array ( ) ) [text:protected] => Dashboard [href:protected] => http://website.com/demo/admin/dashboard [title:protected] => [confirm:protected] => )

    (END DBG)

  • This one looks OK & so would not have cause
        'error: Call to a member function getName() on a non-object..'
    - because there is an object here,

    (re-typed that dump for readability..)

    ElggMenuItem Object (
        [data:protected] =>
        Array (
            [name] => dashboard [contexts] =>
                Array ([0] => admin )
            [section] => administer
            [priority] => 10
            [selected] =>
            [parent_name] =>
            [parent] =>
            [children] => Array ( )
            [itemClass] => Array ( )
            [linkClass] => Array ( )
        )
        [text:protected] => Dashboard
        [href:protected] => http://website.com/demo/admin/dashboard
        [title:protected] =>
        [confirm:protected] =>
    )

    TRY this - small change in code -
    * I removed the exit() -
    so it should preceed with whatever logic
    and hopefully the dbg text will be still
    quite readable afterwards.

        while(!$found && (++$index < $count))
        {
            // :DC: (START DBG)
            echo"<h2>(START DBG) ITEM_NAME= ($item_name)</h2>";
            echo"<h2>(DUMP MENU @ $index of max=$count ? )</h2>";
            echo"<hr>TRY DUMP MENU[]:=";// what is current menu item content?
            print_r($menu[$index]);
            echo"<hr>END - TRY DUMP MENU[]";
            if(is_object($menu[$index]))//is menu item an object?
                echo"<hr><h2>IS OBJECT ? YES</h2>";
            else
                echo"<hr><h2>IS OBJECT ? ERROR</h2>";
            echo"<h2>(END DBG)</h2>";
            //exit(); //:DC: kill rhe exit - let's see what object is when error happens
            // I expect the print_r to dump <empty> - at time of that call..non-object error.
            // :DC: (END DBG)
            if($menu[$index]->getName() === $item_name)

    And BTW - 2am for me - I'm gonna crash after this and look moare later, hasta manana amigo.

    The problem still remains --
    what the heck is in that menu array
    when the error happens --
    and whodunit ?;-)

     

  • @Everyone, thanks for all the help. I think I found the bug. I had the wrong assumption on how elgg_unregister_menu_item() works. I thought after removing a menu item it re-packs the array, but it actually is leaving a gap in it. So after elgg_unregister_menu_item, the menu array might look like:

    0 => menu_item1

    1 => menu_item2

    2 => menu_item3

    4 => menu_item5

    Notice the missing 3rd index. So going over an array like this with a simple incremental counter is a fundamental mistake. When I hit index = 3, it will be pointing to an empty element, and will throw the above error. Only a handful of plugins use elgg_unregister_menu_item, that's why I could not reproduce the issue (didn't have any of those plugins).

    Thanks for your patience and contribution in finding this bug. Will be uploading a fix today.

  • Hmm... It *is repacked - but the manual indexing clobbers the array-walk - ;-) => so not the manual control + $found - but should have been 'foreach' iterate and 'break' out of the loop -- or simply predicate the 'if object' on array element process.

  • @Everyone, the new version (1.0.2) is available now, please report back on the new version's page if it fixed your problems. Thanks again for the contribution!

  • Hmm.. Googled a bit.. Just switched the true and false, and it works. This should have something to do with the return on false giving an error.

    @mrCoffee, does this work for your also?

    @Andras, the elgg_unregister_menu_item is recommend to use for getting rid of the elgg logo in themes..

    function roles_find_menu_index($menu, $item_name) {
        $index = -1;
        $found = true;

        if (is_array($menu)) {
            $count = count($menu);
            while(!$found && (++$index < $count)) {

                if ($menu[$index]->getName() === $item_name) {
                    $found = false;
                }
            }
        }
        return $found ? $index : true;
    }

  • the updated version of Roles works!

    If at First You Don't Secede

    Rename it (1.0.2)

    :D

Arck Interactive

You imagine. We create. We develop custom social networks, content management systems and other rich internet applications. We help entrepreneurs and creative agencies breathe life into their visions. Let's start a conversation!

Stats

  • Category: Uncategorized
  • License: GNU General Public License (GPL) version 2
  • Updated: 2017-5-27
  • Downloads: 9055
  • Recommendations: 44

Other Projects

View Arck Interactive's plugins