• onUserSave am I doing it right?[Solved]#

  • zoadie Reply #1, 3 months, 2 weeks ago

    Reply
    Hi!
    I'm trying to automatically create a "ResourceGroup", a "Resource" and an "UserGroup" for each new registered user.

    I created the following plugins onUserSave:
    <?php
    //create a unique ResourceGroup for each user
    $ID = $user->get('id');
    $response = $modx->runProcessor('security/resourcegroup/create',array('name' => 'ResourceGroup-'.$ID));
    if ($response->isError()) {
        return $response->getMessage();
    }
    $resourceGroupArray = $response->getObject();
    return 'The Resource Group "'.$resourceGroupArray['name'].' was created with ID '.$resourceGroupArray['id'];


    <?php
    //create a Resource for each new user
    $ID = $user->get('id');
    $response = $modx->runProcessor('resource/create',array('pagetitle' => 'Resource-'.$ID, 'published' => 1));
    if ($response->isError()) {
        return $response->getMessage();
    }
    $resourceArray = $response->getObject();
    return 'The Resource"'.$resourceArray['name'].' was created with ID '.$resourceArray['id'];
    

    <?php
    //create a userGroup for each new user
    $ID = $user->get('id');
    $response = $modx->runProcessor('security/group/create',array('name' => 'UserGroup-'.$ID));
    if ($response->isError()) {
        return $response->getMessage();
    }
    $userGroupArray = $response->getObject();
    return 'The User Group "'.$userGroupArray['name'].' was created with ID '.$userGroupArray['id'];
    


    My questions are:
    1. How can I assign User-X to UserGroup-X
    2. How can I assign Resource-X to ResourceGroup-X
    3. Is there a way to have all this code in only one plugin. I tried but it doesn't work.

    I'm quite familiar with the Modx basics but I want to learn more about the advanced features and Developing with Modx and your help will be greatly appreciated.

    ps: I'm using Revo 2.2-pl2


  • BobRay Reply #2, 3 months, 2 weeks ago

    Reply
    You should be able to do it in a single plugin if you leave out the return statements (or just put one at the end).

    The code to add the users and resources to the groups looks like this:

    <?php
    $user->joinGroup('GroupName');
    $resource->joinGroup('GroupName');


    You already have the $user object. The $resource object may be in the $resourceArray, I'm not sure. If not, you can get it with getObject() using the ID.


    ---------------------------------------------------------------------------------------------------------------
    PLEASE, PLEASE specify the version of MODX you are using . . . PLEASE!
    MODx info for everyone: http://bobsguides.com/modx.html


  • zoadie Reply #3, 3 months, 2 weeks ago

    Reply
    Thanks Bob!
    Wooow, soon you are reaching your 11.000 post. )

    I'm getting closer to what I want to achieve. This is the latest code:
    <?php
    //get the user id
    $name = $user->get('name');
    $ID = $user->get('id');
    
    //create a new resource
    $object = $modx->newObject('modDocument');
    $object->set('pagetitle', 'ResourceUser-'.$ID);
    $object->set('published', '1');
    $object->setContent('This will be the content of the new doc.');
    $object->set('description', 'I created this doc in a snippet');
    $object->set('template', '3');
    $object->set('parent', '2');
    $object->set('menuindex', '1');
    $object->set('publishedby', $ID);
    $object->save();
    
    //create a new resourceGroup
    $resourceGroup = $modx->newObject('modResourceGroup');
    $resourceGroup->set('name','ResourceGroup-'.$ID);
    $resourceGroup->save();
    
    //add the resource to it's resourceGroup
    $object->joinGroup($resourceGroup);
    $object->joinGroup('AllPagesResourceGroup');
    
    //create a new userGroup
    $userGroup = $modx->newObject('modUserGroup');
    $userGroup->set('name', 'UserGroup-'.$ID);
    $userGroup->save();
    
    //add the new user the it's userGroup
    $user->joinGroup($userGroup->get('id'),'CustomEditor');
    
    //access
    $resourceGroupAccess = $modx->newObject('modAccessResourceGroup');
    $resourceGroupAccess->set('target', $resourceGroup->get('id'));
    $resourceGroupAccess->set('principal_class', 'modUserGroup');
    $resourceGroupAccess->set('principal', $userGroup->get('id'));
    $resourceGroupAccess->set('authority', 9);
    $resourceGroupAccess->set('policy', 13 ); // 
    $resourceGroupAccess->set('context_key', 'mgr');
    $resourceGroupAccess->save();
    
    $contextAccess = $modx->newObject('modAccessContext');
    $contextAccess->set('target', 'mgr');
    $contextAccess->set('principal_class', 'modUserGroup');
    $contextAccess->set('principal', $userGroup->get('id'));
    $contextAccess->set('authority', 9); // CustomEditor
    $contextAccess->set('policy', 13 ); // a modified ContentEditor policy
    $contextAccess->save();
    
    //the ACL for the web context
    $contextAccess = $modx->newObject('modAccessContext');
    $contextAccess->set('target', 'web');
    $contextAccess->set('principal_class', 'modUserGroup');
    $contextAccess->set('principal', $userGroup->get('id'));
    $contextAccess->set('authority', 9); // CustomEditor
    $contextAccess->set('policy', 13 ); // a modified ContentEditor policy
    $contextAccess->save();
    
    


    I'm still having some problems.
    I can't see anything in the Resource Tree when I'm logged as UserX.
    I created one ResourceGroup "AllPages" and I assigned the "Adminstrator" Group to it
    (minim role: Super User; Acces Policy: Resource; Context: mgr)

    The plugin creates automatically ResourceGroups "ResourceGroup-X" for each UserX
    (minim role: CustomEditor-9; AccesPolicy: Resource; Context: mgr)

    Is there anything I'm missing about ACL?


  • zoadie Reply #4, 3 months, 1 week ago

    Reply
    It's working now.
    I followed these tutorials:
    http://bobsguides.com/revolution-permissions.html
    http://bmv-interactive.com/home/modx-acl-tutorial.html

    I missed the ACL for the web context. The code above it's updated.

    What I wanted to accomplish was to create a personal Resource for each new user. There is no easy way to do that right now in Modx so I had to do the following:
    1. create a plugin with onUserSave event
    2. when a new UserX is created then a ResourceX, ResourceGroupX, UserGroupX with the proper ACLs.

    I still have to figure out:
    1. how to extend the modUser with a field "Department" which will be a drop-down list with some of the Resources I already created as "Departments Containers"

    2. to create a Custom Resource Class extending the modResource with 2 more content areas (, , ) and one image field

    But this is a totally different story...


  • BobRay Reply #5, 3 months, 1 week ago

    Reply
    Sounds good. It's not too difficult to add a new field to the user form in OnUserFormRender. and it will be available in the $_POST array in OnUserFormSave (modified from an example in the book):

    <?php
       // $value =  //set the value here
          $fields = '<div class="x-form-item x-tab-item">
                <label class="x-form-item-label" style="width:152px;">
                    <b>Department</b></label>
                <div class="x-form-element">
                    <input type="text" name="department" value="'. $v .
                        '" class="x-form-text x-form-field" />
                </div>
          </div>';
    


    That's for a straight text field, but should give you the idea.

    If you'd rather not extend the user object, you can save it as a User Setting or as an extended user field pretty easily.


    ---------------------------------------------------------------------------------------------------------------
    PLEASE, PLEASE specify the version of MODX you are using . . . PLEASE!
    MODx info for everyone: http://bobsguides.com/modx.html


  • faolie Reply #6, 4 weeks, 1 day ago

    Reply
    Wow! That's a great plugin. I wanted to take a wee bit further and enable newly created users (via login.register) to login straight to 'their' resource. Since each new user is part of a unique usergroup, I just used redirectUsergroups to redirect the login to their resource. So userA logs in on the home page and is taken straight to their resource for editing via newsPub. So far so good.

    What I can't figure out is how to add the new usergroup to the redirectUsergroups snippet property values. So if the property looks like &redirs=`UserGroup-21:36,UserGroup-20:35...` is it possible to auto add new usergroups/resources as they're created? I guess all that's required is to append the new usergroup/resource to the snippet's property values but I'm not sure where to start.

    Any pointers as to how I'd achieve this?


  • BobRay Reply #7, 4 weeks ago

    Reply
    It depends on whether you're using the snippet's default properties or a property set and whether the property is set in the snippet tag or not. In any case, it's definitely doable.


    ------------------------------------------------------------------------------------------
    PLEASE, PLEASE specify the version of MODX you are using.
    MODX info for everyone: http://bobsguides.com/modx.html


  • faolie Reply #8, 4 weeks ago

    Reply
    Maybe a better way to do this is to use the logic of redirectUsergroups in a post-hook snippet for Login. Post-hook should gather all usergroups and test to see which group logged in user belonged to, then redirect user to the resource in the group. Something like

    foreach usergroup {
    if ($modx->user->isMember(usergroupA){
    $url=$modx->makeUrl(resource);
    }
    }
    return $modx->sendRedirect($url);

    I think that that's really what's needed. There's no point in continually expanding the redirectUsergroups snippet if we can simply interrogate the usergroups directly. But I've little idea of how to code this either. Help anyone please?


  • BobRay Reply #9, 4 weeks ago

    Reply
    Post-hook should gather all usergroups and test to see which group logged in user belonged to, then redirect user to the resource in the group.

    Here's the problem: User groups don't have any resources attached to them. You can get the user groups that the user belongs to, but you need a way to find the appropriate *resource group* for each one.

    If they have the same names (the resource group and the user group), you can do something like the following. This is off the top of my head and probably not correct, but it should get you started:

    /* get the modUserGroupMember entries for the user */
    $ugms = $modx->user->getMany('UserGroupMembers');
    
    /* loop through them until we find a same-name resource group */
    foreach ($ugms as $ugm) {
         $userGroup = $ugm->getOne('UserGroup');
         $name = $userGroup->get('name');
    
         $resourceGroup = $modx->getObject('modResourceGroup', array('name' => $name));
    
         if ($resourceGroup) {
              /* found one - redirect to its first resource */
              $rgrs = $resourceGroup->getMany('ResourceGroupResources');
              if ( ! empty ($rgrs)) {
                      $resource = $rgrs[0] ->getOne('Resource');
                      $id = $resource->get('id');
                      $url = $modx->makeUrl($id, "", "", "full");
                      $modx->sendRedirect($url);
    
              }
    
         }
    
    
    }



    BTW, here are some resources I consulted for the code above:

    http://bobsguides.com/modx-object-quick-reference.html#modUser

    http://bobsguides.com/modx-object-quick-reference.html#modUserGroupMember

    http://bobsguides.com/modx-object-quick-reference.html#modUserGroup

    http://bobsguides.com/modx-object-quick-reference.html#modResourceGroup

    http://bobsguides.com/modx-object-quick-reference.html#modResourceGroupResource


  • faolie Reply #10, 3 weeks, 5 days ago

    Reply
    BobRay, thanks again. Almost there I think. I've identified the usergroup a slightly different way and thought that getting the resource from the resourcegroup would be easier, but I'm struggling to get it to work. If I simplify your example and just give it the resourcegroup $name for line 9, it throws an error (ie goes to white screen). Seems to be line 15 that's causing this error but I don't really understand what's going on. I've looked at your references a hundred times and I still don't get it.

    To recap, I can retrieve the usergroup name from the user's id. As it's the same as the resourcegroup name, how do I get the resource to do the redirect?


    Thanks