8.4+ How to assign user attributes only to users in certain groups

Permalink
I have 2 sets of user attributes: Set1 and Set2, each having various attributes. I have 2 user groups: Group1 and Group2.

I don't want ALL attributes to be displayed and required for all users.

How can I programmatically set/assign attributes of Set1 only to the users from Group1 and those of Set2 only to those from Group2?

Is there any way to override the concrete/single_pages/account/edit_profile.php in a package?

Thank you.

linuxoid
 
linuxoid replied on at Permalink Reply
linuxoid
I found one way of doing that - adapting thishttps://legacy-documentation.concrete5.org/tutorials/overriding-prof... for v8:

1. create folder 'account' in single_pages, controllers/single_page, elements of your package
2. copy edit_profile.php, edit_profile.php, menu.php from corresponding core folders:
- single_pages/account/edit_profile.php
- controllers/single_page/account/edit_profile.php
- elements/menu.php
3. add the following code to the package controller methods:
private function install()
{
    $pkgID = $this->app->make(PackageService::class)->getByHandle('your_package_handle')->getPackageID();
    $page = Page::getByPath('/account/edit_profile');
    $page->update(array('cName'=>'Edit Profile'));
    $cID = $page->getCollectionID();
    $db = $this->app->make('database')->connection();
    $q = 'update Pages set pkgID = ? where cID = ?';
    $v = [$pkgID, $cID];
    $db->executeQuery($q, $v);
}
public function uninstall()
{
    $page = Page::getByPath('/account/edit_profile');
    $page->update(array('cName'=>'Edit Profile'));

4. Edit the copied files to suit
5. Install the package

Any other account page can be similarly overridden.

Is there a better way? Can the DB stuff be done with Doctrine?
linuxoid replied on at Permalink Reply
linuxoid
Well, it turns out it's only half of the story.

I add 2 sets of user attributes: 'Job Seeker' and 'Employer'. And attributes in each set have the following properties set:
$key = new UserKey();
$key->setAttributeKeyHandle($handle);
$key->setAttributeKeyName(t($name));
if ($handle != 'job_seeker_id') {
    $key->setAttributeKeyDisplayedOnProfile(true);
    $key->setAttributeKeyDisplayedOnMemberList(true);
    $key->setAttributeKeyEditableOnProfile(true);
    $key->setAttributeKeyEditableOnRegister(true);
    if (!in_array($handle, ['job_seeker_given_name', 'job_seeker_address'])) {
        $key->setAttributeKeyRequiredOnProfile(true);
    }
}

to make sure the user fills in the form fields in the profile.

So I've overridden the edit_profile page and filter the attribute keys:
$job_seeker_attributes = ['job_seeker_last_name', 'job_seeker_first_name', 'job_seeker_given_name', 'job_seeker_address', 'job_seeker_phone'];
$employer_attributes = ['employer_company', 'employer_contact', 'employer_address', 'employer_phone'];
if (is_array($attribs) && count($attribs)) {
    foreach ($attribs as $ak) {
        if (($user->inGroup(Group::getByName('Job Seeker')) && in_array($ak->getAttributeKeyHandle(), $job_seeker_attributes)) || 
            ($user->inGroup(Group::getByName('Employer')) && in_array($ak->getAttributeKeyHandle(), $employer_attributes))) {
            echo $profileFormRenderer
                ->buildView($ak)
                ->setIsRequired($ak->isAttributeKeyRequiredOnProfile())
                ->render();
        }
    }
}

but now the problem is even though I'm not showing a set of attributes for the user in a group, the form checks are done for ALL attributes for BOTH sets, so I've got empty form fields errors for fields which are not shown.

Where can I change that? How can I restrict attributes to certain user groups?