MODX Community

Assign user to one ressource - Front -end edition

I have to create a site where society can make a profile and edit it.
I have done user creation with Login Extra.
I think i can “link” user and ressource by using user custom fields and let them edit the content of ressource with NewPublisher Extra

But i cant figure how to automaticaly create the ressources and fill/edit the TV in front-end
I have to assign different model for this ressource depending on a TV vallue of this ressource
I have to put ressources in a different folder (selected, not selected) depending on TV vallue

i found this solution
https://forums.modx.com/thread/31314/how-to-create-resources-documents-from-the-front-end-with-a-form

and i have to send message to user for let him know the state of his ressources depending TV value or ressource folder location
for this one i dont have any idea, i heard abour hook, prehook and i think it may be the way

(it’s a site who show innovative project and make video on them. I have to sort society depending if they accept to be filmed or not, and i have to send message for user if they are selected or not for the video making)

Have you some advices ?

1 Like

I’m not sure if this article is what you want, but it might be.

1 Like

Thanks Bob, I take some time to see if i really wish to deliver ressources access to web user and the answer is no. I prefer to store data from users in extended user field and update an associated resource with moderator aproval.

I will use a form with a snippet in hook to create a new modx ressources from input form, get the id of the new resource created and put it in an extended user field.
may be newpublisher can do this easily but i prefer to manage it by snippet

process will be liket this:
i have to check if user are logged in:
[[!isLoggedIn? &ctxs=`web`]]
and then if he have an resource id on a user extended field that mean he have already made one resource so i hide my chunk form

if not, i have to show a form who will create only one ressource once.
template of the ressource will be defined by checkbox from the form
some field will be used to fill resource field and some other one will be stored to extended user fields

i dont really know how to acces extended user fields from snippet, i ear about json , i imagine i will need to parse data en check value but i dont know if i had to make/name extended user fields at user creation or if i can make it with snippet

1 Like

The extended fields are in the user profile (modUserProfile) object.

So:

/* Assuming that you have the $user object */

$profile = $user->getOne('Profile');
if ($profile) {
    $extendedFields = $profile->get('extended');
} else {
    /*  user has no profile */
}
/* $extendedFields is a regular PHP associative array. */
$value = $profile['some_field']

/* If you need to change the value, get the extended fields as above, then: */

$profile['some_field'] = 'newValue';
$profile->save();

This is another option: ClassExtender.

1 Like

i can’t make it work :confused:

Fatal error: Uncaught Error: Call to a member function getOne() on null

i found this tread in old modx forum : https://forums.modx.com/thread/44021/accessing-extended-fields-revo-user-management

i make a snippet call getUserExtendedFields

<?php
$profile = $modx->user->getOne('Profile');
$modx->toPlaceholders($profile->get('extended'), 'userext');
$extended = $profile->get('extended');
echo $extended['RessourcesId'];
echo $extended['Test'];
if($extended['RessourcesId'] == ''){ echo "Ressources Id vide"; return $modx->getChunk('InscriptionForm');}else{echo $extended['RessourcesId'];}

and put placeholder in model

PlaceHolder Ressource ID : [[+userext.RessourcesId]]<br/>
PlaceHolder Test : [[+userext.Test]]<br/>

it works BUT, when i disconnect the user and reconnect another user witout any extend field… it show me the last result. i clean web browser cache, event use another web browser, i always saw the last request…
i have to go to modx administration -> clean cache to get the snippet work properly with new user.
what am i doing wrong ?

1 Like

ok… my fault i call snippet with cache: [[getUserExtendedFields]].
using uncached make it work : [[!getUserExtendedFields]]

1 Like

About my code above. Notice the very first line:

/* Assuming that you have the $user object */

$profile = $user->getOne('Profile');

If you don’t already have the user object, you have to get it before calling getOne().

In the front end, that would be either this at the top:

$user = $modx->user;

or just changing the code to:

$profile = $modx->user->getOne('Profile');
1 Like

haaa ok $user : $ for variable
i just needed to fill it with user data
thanks

1 Like

It works.
i use a form to create a ressource with user id in tv and save the ressource id in the extend field of the user`

i call my snipet “CreateRessource” in a hook

[[!FormIt?
    &hooks=`spam,email,redirect,CreateResource,FormItSaveForm

and there is my snippet :

<?php
/* variables initialisation */
$parent = 9;
$doc = $modx->getObject('modResource',array('id'=>$hook->getValue('resource_id')));
$userid = $modx->user->get('id');

/* Initialisation of future Ressource*/
if (empty($doc)){
    $doc = $modx->newObject('modResource');
    $doc->set('createdby', $userid);}else{$doc->set('editedby', $userid);
        
    }
    
/* we set element who are not in the form*/
$doc->set('parent', $parent);

/*we make a loop on every fiel and get its value*/
$allFormFields = $hook->getValues(); 
foreach ($allFormFields as $field=>$value)
{
    if ($field == 'projectname'){
        $doc->set('pagetitle', $value);
    }
    
    if ($field == 'projectdescription'){
        $doc->set('content', $value);
    }
    
   if ($field == 'emission'){
       if ($value[0] == "oui"){ $doc->set('template', '13');}else{ $doc->set('template', '12');}
    }
    
/*--------TV--------*/
    if ($field == 'firstname'){
        $firstname = $value;
    }
    
    if ($field == 'lastname'){
        $lastname = $value;
    }
    
    if ($field == 'email'){
        $email = $value;
    }
    
    if ($field == 'phone'){
        $phone = $value;
    }
    
    if ($field == 'adresse'){
        $adresse = $value;
    }
    
    if ($field == 'postcode'){
        $zipcode = $value;
    }
    
    if ($field == 'town'){
        $town = $value;
    }
    
    if ($field == 'projecturl'){
        $url = $value;
    }

   /*if ($field !== 'spam' && $field !== 'resource_id'  && $field !== 'template'){
         $doc->set($field, $value);
    }*/

}

/*we save the ressource one time to set the template and get the right tv*/
$doc->save();

/*we create the user extended field*/
$id = $doc->get('id');
$profile = $modx->user->getOne('Profile');
$extended = array();
$extended = $profile->get('extended');
$extended = ['RessourcesId' => $id];
$profile->set('extended', $extended);
$profile->save();

/*now we can set TV*/
$doc->setTVValue(30,$userid);
$doc->setTVValue( 7,$firstname);
$doc->setTVValue( 8,$lastname);
$doc->setTVValue( 6,$email);
$doc->setTVValue( 9,$phone);
$doc->setTVValue( 4,$adresse);
$doc->setTVValue( 12,$zipcode);
$doc->setTVValue( 10,$town);
$doc->setTVValue( 11,$url);
$doc->save();

return true;

and in a user page acceced by login i put a snippet to retreave information of the right ressource

<?php
/* we get user identification */
$user = $modx->user->get('id');
$modx->setPlaceholder('userID',$user);

/*we retreave ressource id stored in extended fiels and show it in a placeholder*/
$profile = $modx->user->getOne('Profile');
$extended = $profile->get('extended');
$RessourceID=$extended['RessourcesId'];
$modx->setPlaceholder('StartupID',$RessourceID);


$resourceObj = $modx->getObject('modResource', $RessourceID);

/* if we get one we show tv from the ressource id in placeholders*/

if ($resourceObj) {
$modx->setPlaceholder('StartupName',  $resourceObj->get('pagetitle'));
$modx->setPlaceholder('StartupFirstName',  $resourceObj->getTVValue('StartupFirstNameTV'));
$modx->setPlaceholder('StartupLastName',  $resourceObj->getTVValue('StartupLastNameTV'));
$modx->setPlaceholder('StartupPhone',  $resourceObj->getTVValue('StartupPhoneTV'));
$modx->setPlaceholder('StartupUrl',  $resourceObj->getTVValue('StartupUrlTV'));
$modx->setPlaceholder('startupEmail',  $resourceObj->getTVValue('StartupEmailTV'));
$modx->setPlaceholder('StartupAdress',  $resourceObj->getTVValue('StartupAdressTV'));
$modx->setPlaceholder('StartupTown',  $resourceObj->getTVValue('StartupTownTV'));
$modx->setPlaceholder('StartupZipcode',  $resourceObj->getTVValue('StartupZipcodeTV'));
}
1 Like

I’m glad you got it working. :slight_smile:

Just a thought: there are several drawbacks to using the extended field to store user data. You can read about them here. It’s a whole lot faster to extend the modUser object with ClassExtender or your own code. It’s also way easier to search and sort users based on the data values once you do this.

Also, for a place to put the user’s ID in another table, consider is this, usually unused, field of the modUser Object:

remote_key (string)

It’s usually used if the user is also in some remote DB in addition to the MODX DB, but it’s perfect for storing the user’s ID in another table as you’d do with a custom user object.

Most of the time, you already have the modUser object so the value is already in memory, giving you super-fast retrieval.

3 Likes

Yes, one of the weaknesses of Modx is the lack of user data, the point of Modx was always a clean core and extended user data was not a focus, You’ve got to draw the line somewhere, and they did.

Extended fields are ok if you have just a couple of extra data points, but that’s about it. While there is a function I believe to create more within the same structure, its just not designed for the data we might want in 2019 and beyond.

I always thought the opposite - as in almost too many! :slight_smile:
There’s a tremendous amount of user fields in the modUserProfile table that can be used out of the box.
You can store custom user data as JSON in the extended fields, you can store data as user settings, or as Bob said you can extend the modUser class with your own custom db table.
Hardly a lack of user data I reckon! :wink:

1 Like

Fair point, that is enough for many developers.

However if you have a lot of users, and need to regularly access their data from the JSON, I believe that gets pretty inefficient.

But certainly its enough if you just want to let the user input some data so you have user stats

1 Like

True, if you’re going to have tens of thousands of users then the extended fields are not the best choice.
They’re meant to quickly add fields to users for smaller sites.

If you’re building something where you expect big numbers, extending modUser with a custom database table gives you virtually unlimited extra fields to work with.
MODX gives you different options for different situations and I consider that a strength.

1 Like

You have a good point. Certainly the extra fields are useful and I didn’t even know about user settings

1 Like