Core Event Listener for modify_username_string

Discussion forum for Extension Writers regarding Extension Development.
Post Reply
Cohaven
Registered User
Posts: 14
Joined: Wed Oct 18, 2017 2:53 pm

Core Event Listener for modify_username_string

Post by Cohaven »

Hi,

I'm trying to create an extension for phpBB3.1 to use on my forum. This extension is meant to replace the username that is displayed on the template pages with the custom profile field "display_name".
The yml and the composer.json files are in place and the extension is enabled in ACP.

I'm having trouble understanding when the listener will fire this event (before, during, after the core function is used), and what exactly should I be modifying in the $event?

I tried modifying the $username_string and saving it back into the $event, but that strips away all the link functionality and styling of the $username_string that the event returns.

The current listener code:

Code: Select all

<?php

namespace company\displayname\event;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class main_listener implements EventSubscriberInterface
{
    protected $pfm;
    
    public function __construct(\phpbb\profilefields\manager $pfm, \phpbb\template\template $template)
    {
        $this->pfm = $pfm;
        $this->template = $template;
    }
    
    /**
     * Assign functions defined in this class to event listeners in the core
     *
     * @return array
     */
    static public function getSubscribedEvents()
    {
        return array(
            'core.modify_username_string' => 'replace_username_with_display_name',
        );
    }

    public function replace_username_with_display_name($event)
    {
        $user_id = $event['user_id'];
                
        //retrieve the display name profile field for the user
        if(!empty($user_id))
        {
            $userProfileFields = $this->pfm->grab_profile_fields_data($user_id);
            if(!empty($userProfileFields[$user_id]['display_name']['value']))
            {
                $username_string = $userProfileFields[$user_id]['display_name']['value'];
                $this->template->assign_var('USERNAME', $username_string);
            }

        }       
    }
}
As you can see, I've tried replacing just the USERNAME template variable to preserve the link and styling, but it doesn't seem to work.

What are your suggestions on how to handle this sort of extension functionality? I'd also appreciate some tips on how to figure out what the $event and $template variables contain. I've tried printing them out to file, but they lock up the system and give a memory allocation error. I tried looking at the phpbb "core" files, but they seem to mostly define the functions, not the data.
User avatar
RMcGirr83
Former Team Member
Posts: 22016
Joined: Wed Jun 22, 2005 4:33 pm
Location: Your display
Name: Rich McGirr

Re: Core Event Listener for modify_username_string

Post by RMcGirr83 »

Try

Code: Select all

public function replace_username_with_display_name($event)
{
	$user_id = $event['user_id'];
	$username_string = $event['username_string'];
	//retrieve the display name profile field for the user
	if(!empty($user_id))
	{
		$userProfileFields = $this->pfm->grab_profile_fields_data($user_id);
		if(!empty($userProfileFields[$user_id]['display_name']['value']))
		{
			$username_string = $userProfileFields[$user_id]['display_name']['value'];
		}
	}
	$event['username_string'] = $username_string;
}
I don't believe you need to change the template.
Former Modifications/Extensions Team Member | My extensions | github | All requests for support via PM will be ignored
Appreciate the extensions/mods/support then buy me a beer Image
Cohaven
Registered User
Posts: 14
Joined: Wed Oct 18, 2017 2:53 pm

Re: Core Event Listener for modify_username_string

Post by Cohaven »

I'm not sure how what you suggest is any different from what I said I already tried:
"I tried modifying the $username_string and saving it back into the $event, but that strips away all the link functionality and styling of the $username_string that the event returns."

I have managed to replace just the username text within $username_string, not the whole variable, with the following adjustments:

Code: Select all

    public function replace_username_with_display_name($event)
    {
        $user_id = $event['user_id'];
        $display_name = $this->get_display_name($user_id); //put this in a separate function as I will be reusing the retrieval of the display name
        $event['username_string'] = str_replace($event['username'], $display_name, $event['username_string']);
    }
However, there are still pages that show the username instead of the display name, such as the memberlist_view.html. My first instinct was to modify the USERNAME template variables that the page uses. Although the event and function don't seem to fire at all...

Code: Select all

<?php

namespace company\displayname\event;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class main_listener implements EventSubscriberInterface
{
    protected $pfm;
    
    public function __construct(\phpbb\profilefields\manager $pfm, \phpbb\template\template $template)
    {
        $this->pfm = $pfm;
        $this->template = $template;
    }
    
    /**
     * Assign functions defined in this class to event listeners in the core
     *
     * @return array
     */
    static public function getSubscribedEvents()
    {
        return array(
            'core.modify_username_string' => 'replace_username_with_display_name',
            'memberlist_view_content_prepend' => 'replace_username_in_templates',
        );
    }

    public function replace_username_with_display_name($event)
    {
        $user_id = $event['user_id'];
        $display_name = $this->get_display_name($user_id);
        $event['username_string'] = str_replace($event['username'], $display_name, $event['username_string']);
    }
    
    public function replace_username_in_templates($event){
        $user_id = $event['user_id'];
        $display_name = $this->get_display_name($user_id);
        file_put_contents('/log_displayname_ext.txt',"\ndisplay_name: ". $display_name,FILE_APPEND);//TEST
        $this->template->assign_vars(array(
            'USERNAME'   => $display_name,
            'L_CONTACT_USER' => "CONTACT $display_name",
            )
        );
    }
    
    public function get_display_name($user_id){                      
        //retrieve the display name profile field for the user
        if(!empty($user_id))
        {
            $userProfileFields = $this->pfm->grab_profile_fields_data($user_id);
            if(!empty($userProfileFields[$user_id]['display_name']['value']))
            {
                $display_name = $userProfileFields[$user_id]['display_name']['value'];
                return $display_name;
            }
        }
    }
}
However, I anticipate that a similar issue might arise on other pages, so there will be a need to listen to a lot of page-specific events and replacing their template variables. Is this the best way to do this?
Post Reply

Return to “Extension Writers Discussion”