Auto Assign To Group Based On Age.

Xarcell

Well-known member
Is there anyway to modify xF to auto-assign a person to a secondary group based on age?

For example, let's say I create groups 5-70. Then if a person puts in his/her age as "13", that person is automatically placed in group 5. If a person puts in 14 as age, they are automactically placed in group 6, so on and so forth.

Placed in group as secondary, not primary.
 
I think you could do this at the datawriter level. Override the pre-save method and check if the user has specified all the b'day fields (day, month, year). If they are set, apply your logic for mapping the age to a usergroup, and set the secondary groups accordingly.

(untested)
PHP:
class Xarcell_DataWriter_User extends XFCP_Xarcell_DataWriter_User
{
	protected function _preSave()
	{
		parent::_preSave();

		if ($this->get('dob_day') && $this->get('dob_month') && $this->get('dob_year'))
		{
			// Get age
			$age = $this->getModelFromCache('XenForo_Model_UserProfile')->calculateAge(
				$this->get('dob_year'), $this->get('dob_month'), $this->get('dob_day')
			);

			// Get mapped usergroup
			$newUsergroup = Xarcell_Helper_Usergroup::getUsergroupByAge($age);

			// Get existing secondary usergroups as an array
			// Append your $newUsergroup to the array, if not already present

			// Set the new list of secondary usergroups
			$this->setSecondaryGroups($secondaryUsergroups);
		}
	}
}
 
Basically, you need to write the logic to determine which group to add them too. Here's the PHP you'll need (NOT TESTED):
PHP:
class Xarcell_DataWriter_User extends XFCP_Xarcell_DataWriter_User
{
    protected function _preSave()
    {
        parent::_preSave();

        if ($this->get('dob_day') && $this->get('dob_month') && $this->get('dob_year'))
        {
            // Get age
            $age = $this->getModelFromCache('XenForo_Model_UserProfile')->calculateAge(
                $this->get('dob_year'), $this->get('dob_month'), $this->get('dob_day')
            );

            // Get mapped usergroup
            $newUsergroup = $this->_getUsergroupByAge($age);

            // Get existing secondary usergroups as an array
            $secondaryUsergroupsString = $this->get('secondary_group_ids');
            $secondaryUsergroups = explode(',', $secondaryUsergroupsString);
            foreach($newUsergroup AS $id)
            {
            	// if its not in the array...
            	if(!in_array($id, $secondaryUsergroups))
            	{
            		// add it.
            		$secondaryUsergroups[] = $id;
            	}
            }
            // Set the new list of secondary usergroups
            $this->setSecondaryGroups($secondaryUsergroups);
        }
    }
    protected function _getUsergroupByAge($age)
    {
    	$newGroups = array();
    	if($age > 5 && $age < 10)
    	{
    		// Set the number here to be an ID of the 6-9 group
    		$newGroups[] = 4;
    	}
    	if($age >= 10 && $age <= 20)
    	{
    		// Set the number here to be an ID of the 10-20 group	
    	}
    	return $newGroups;
    }
}

Now, you'll have to modify _getUsergroupByAge() and add more if() statements. >= and <= mean greater than OR equal too / less than OR equal too so, you'll use this if you want them to be included in the range. The first one exludes them. You'll need the group IDs from the ACP where it says $newGroups[] = X;.
 
Like a I said, I don't know php, but would it be something like this:

Basically, you need to write the logic to determine which group to add them too. Here's the PHP you'll need (NOT TESTED):
PHP:
class Xarcell_DataWriter_User extends XFCP_Xarcell_DataWriter_User
{
    protected function _preSave()
    {
        parent::_preSave();

        if ($this->get('dob_day') && $this->get('dob_month') && $this->get('dob_year'))
        {
            // Get age
            $age = $this->getModelFromCache('XenForo_Model_UserProfile')->calculateAge(
                $this->get('dob_year'), $this->get('dob_month'), $this->get('dob_day')
            );

            // Get mapped usergroup
            $newUsergroup = $this->_getUsergroupByAge($age);

            // Get existing secondary usergroups as an array
            $secondaryUsergroupsString = $this->get('secondary_group_ids');
            $secondaryUsergroups = explode(',', $secondaryUsergroupsString);
            foreach($newUsergroup AS $id)
            {
            	// if its not in the array...
            	if(!in_array($id, $secondaryUsergroups))
            	{
            		// add it.
            		$secondaryUsergroups[] = $id;
            	}
            }
            // Set the new list of secondary usergroups
            $this->setSecondaryGroups($secondaryUsergroups);
        }
    }
    protected function _getUsergroupByAge($age)
    {
    	$newGroups = array();
    	if($age > 5 && $age < 10)
    	{
    		// Set the number here to be an ID of the 6-9 group
    		$newGroups[] = 4;
    	}
    	if($age >= 10 && $age <= 20)
    	{
    		// Set the number here to be an ID of the 10-20 group
    	}
    	return $newGroups;
    }
}

Now, you'll have to modify _getUsergroupByAge() and add more if() statements. >= and <= mean greater than OR equal too / less than OR equal too so, you'll use this if you want them to be included in the range. The first one exludes them. You'll need the group IDs from the ACP where it says $newGroups[] = X;.


Thanks for your help.

It seems that would be alot of if statements. Every single age, would be applied to a different secondary group. (I plan to make 62 secondary groups for this, ages 13-75)

Wouldn't it be something like:

Code:
        if ($age > 12 && $age < 76)
            $newGroups = $age -8;

If the first secondary group for age(13) is group id # 5, and the last secondary group for age(75) would be secondary group id # 67?
 
If it's set up as such, yes that should work. Although, if you're only adding one group I modify my original code to this:
PHP:
class Xarcell_DataWriter_User extends XFCP_Xarcell_DataWriter_User
{
    protected function _preSave()
    {
        parent::_preSave();

        if ($this->get('dob_day') && $this->get('dob_month') && $this->get('dob_year'))
        {
            // Get age
            $age = $this->getModelFromCache('XenForo_Model_UserProfile')->calculateAge(
                $this->get('dob_year'), $this->get('dob_month'), $this->get('dob_day')
            );

            // Get mapped usergroup
            $newUsergroup = $this->_getUsergroupByAge($age);

            // Get existing secondary usergroups as an array
            $secondaryUsergroupsString = $this->get('secondary_group_ids');
            $secondaryUsergroups = explode(',', $secondaryUsergroupsString);
			if($newUsergroup != null)
            {
            	// if its not in the array...
            	if(!in_array($newUsergroup, $secondaryUsergroups))
            	{
            		// add it.
            		$secondaryUsergroups[] = $newUsergroup;
            	}
            }
            // Set the new list of secondary usergroups
            $this->setSecondaryGroups($secondaryUsergroups);
        }
    }
    protected function _getUsergroupByAge($age)
    {
    	$newGroups = null;
    	if($age > 12 && $age < 76)
    		$newGroups = $age - 8;
    	}
    	return $newGroups;
    }
}
 
Ok, I have a stupid question...

Where do I put this php script? To auto-assign all registered user's to there secondary groups?
 
This'll be extending the registration class. You need an event listener. Are you in debug mode?
 
1. Save the given class in /library/Xarcell/DataWriter/User.php

2. Create another file /library/Xarcell/Addon.php with the following contents:
PHP:
<?php

class Xarcell_Addon
{
	public static function load_class_datawriter($class, array &$extend)
	{
		if ($class == 'XenForo_DataWriter_User')
		{
			$extend[] = 'Xarcell_DataWriter_User';
		}
	}
}

3. Go to Admin Panel » Development (tab) » Code Event Listeners » Create New Code Event Listener
Then fill up the fields as shown in the screenshot and save.

create new code event listener.webp


Let us know how it goes.
 
I feel like I'm going to end annoying everyone here...

In beta 5, I see no development tab, but it was there in previous versions...
 
The development tab only appears when you're in debug mode.
To enable it, edit the file /library/config.php and put this on a new line:

PHP:
$config['debug'] = true;
 
Ok, here's what I've done.

Created a folders: "library/Xarcell/DataWriter".

Saved this to a php file (Addon.php) and placed the file in the Xarcell folder:
Code:
<?php

class Xarcell_Addon
{
    public static function load_class_datawriter($class, array &$extend)
    {
        if ($class == 'XenForo_DataWriter_User')
        {
            $extend[] = 'Xarcell_DataWriter_User';
        }
    }
}

?>

Saved this to a php file and placed the file (User.php) in the DataWriter folder.
Code:
<?php

class Xarcell_DataWriter_User extends XFCP_Xarcell_DataWriter_User
{
    protected function _preSave()
    {
        parent::_preSave();

        if ($this->get('dob_day') && $this->get('dob_month') && $this->get('dob_year'))
        {
            // Get age
            $age = $this->getModelFromCache('XenForo_Model_UserProfile')->calculateAge(
                $this->get('dob_year'), $this->get('dob_month'), $this->get('dob_day')
            );

            // Get mapped usergroup
            $newUsergroup = $this->_getUsergroupByAge($age);

            // Get existing secondary usergroups as an array
            $secondaryUsergroupsString = $this->get('secondary_group_ids');
            $secondaryUsergroups = explode(',', $secondaryUsergroupsString);
            if($newUsergroup != null)
            {
                // if its not in the array...
                if(!in_array($newUsergroup, $secondaryUsergroups))
                {
                    // add it.
                    $secondaryUsergroups[] = $newUsergroup;
                }
            }
            // Set the new list of secondary usergroups
            $this->setSecondaryGroups($secondaryUsergroups);
        }
    }
    protected function _getUsergroupByAge($age)
    {
        $newGroups = null;
        if($age > 12 && $age < 100)
            $newGroups = $age - 2;
        }
        return $newGroups;
    }
}

?>

Then I uploaded the folders to my forum root.

Then placed the site in debug mode, went to code event listeners and entered exactly what you shows in the screenshot.

Everything seems ok.

But then when I test register, there it says: "Parse error: syntax error, unexpected T_RETURN, expecting T_FUNCTION in /home/xarcell/public_html/inspireromance.com/library/Xarcell/DataWriter/User.php on line 41"

I see the error in the code, but unsure how to correct it. Should it be:
Code:
    protected function _getUsergroupByAge($age)
    {
        $newGroups = null;
        if($age > 12 && $age < 100)
            $newGroups = $age - 2;

        return $newGroups;
    }

Instead of:
Code:
    protected function _getUsergroupByAge($age)
    {
        $newGroups = null;
        if($age > 12 && $age < 100)
            $newGroups = $age - 2;
        }
        return $newGroups;
    }
 
Yep.

PHP:
	protected function _getUsergroupByAge($age)
	{
		$newGroups = null;
		if($age > 12 && $age < 100)
		{
			$newGroups = $age - 2;
		}
		return $newGroups;
	}
 
Alright, I've tested and it does not seem to work.

What I've done.

The script seemed to work without any obvious errors.

Registered a user with date of birth required. 5-31-1978

Changed a node to private, to see if the node disappears to the registered user. It disappeared. Then I gave permission to group (age 32) to allow everything for that node. The node remains hidden.

Also, when viewing the user profile, no secondary groups where checked.

EDIT: I also gave all permission to that node in surrounding age groups(-/+2), still not working.

Any ideas or suggestions?
 
Found the problem. We were hooking into the wrong function. _preSave gets called a bit late to change secondary usergroups via setSecondaryGroups() function. Hooking into _preSaveDefaults() fixes it...

PHP:
<?php

class Xarcell_DataWriter_User extends XFCP_Xarcell_DataWriter_User
{
	protected function _preSaveDefaults()
	{
		if ($this->get('dob_day') && $this->get('dob_month') && $this->get('dob_year'))
		{
			// Get age
			$age = $this->getModelFromCache('XenForo_Model_UserProfile')->calculateAge(
				$this->get('dob_year'), $this->get('dob_month'), $this->get('dob_day')
			);

			// Get mapped usergroup
			$newUsergroup = $this->_getUsergroupByAge($age);

			// Get existing secondary usergroups as an array
			$secondaryUsergroups = explode(',', $this->get('secondary_group_ids'));
			if($newUsergroup != null)
			{
				// if its not in the array...
				if(!in_array($newUsergroup, $secondaryUsergroups))
				{
					// add it.
					$secondaryUsergroups[] = $newUsergroup;
				}
			}
			// Set the new list of secondary usergroups
			$this->setSecondaryGroups($secondaryUsergroups);
		}

		parent::_preSaveDefaults();
	}

	protected function _getUsergroupByAge($age)
	{
		if($age > 5 && $age < 100)
		{
			return $age - 2;
		}
	}
}
 
Ok, it works flawlessly after some vigorous testing(even changed b-days).

The only thing is I added a closing php tag ?> to your script.

I didn't know you kept doing that intentionally or not.
 
Good to hear it's working fine. :)

And yes, I intentionally omitted the closing php tag. Not really needed.
 
Ok, thanks for all your help. This was the single most important part of my xF installation, to get my site working as needed.

Thanks again.
 
This worked for Beta 5, but after upgrading to beta 6, it stopped. Now when I change the user's age, it will not assign that user to the proper group, unlike before. Any ideas on how to correct this?

I've also been waiting to upgrade to RC1 until I can get this resolved.
Any suggestions?

After more testing, I noticed that if I changed b-day, it re-assigned the user to the proper group, but did not un-assign from previous group. I manually tried removing(unchecking the box) of the previous group and saved, but it doesn't change.
 
Top Bottom