We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 52534
    • 13 Posts
    I've built a few sites now with 40+ unique users who each need their own set of secluded resources and a media folder for uploads. Just learning the Resource Group/User Groups/ACL for a single user took a week and a ton of coffee. Building 40+ Resource/User Groups and setting their contexts and permissions in not a fun task and has caused many errant 503s when I forget to add a WEB context or mess up the user roles.

    Have you guys had any luck maintaining such a site? Do you have tips or tricks? Does every single user really need their own Resource Group/User Group and Media Source to keep their managers private from one another? Is there a magical Extra that handles these things?

    Thanks for any feedback/questions you have.
      Front End Designer + Developer for Eternity
      • 3749
      • 24,544 Posts
      There's no magical extra that I know of, but you can create a plugin or snippet to do everything automatically. It's not a trivial job, but once it's working, you can sit back and relax without worrying about forgetting a step.

      This part of it is relatively straightforward (assuming that you have the user object). It could be a postHook for the Register snippet:

      (untested and off the top of my head)

      /* username is used for resource, user group, and resource group name */
      $uName = $hook->get('username'); 
      
      /* Create the user group and add the user to it */
      $userGroup = $modx->newObject('modUserGroup');
      $userGroup->set('name', $uName);
      $userGroup->save();
      $user = $modx->getObject('modUser', array('username' => $uName));
      $user->joinGroup($uName);
      
      /* Create the User's Resource and Resource Group */
      $doc = $modx->newObject('modDocument');
      $doc->set('pagetitle', $uName);
      $doc->save();
      $resourceGroup = $modx->newObject('modResourceGroup');
      $resourceGroup->set('name', $uName);
      $resourceGroup->save();
      $resource->joinGroup($uName);
      return true;
      
      


      You'd want to add some sanity checks. I think the 'username' entered by the user will be sanitized before it arrives, but check to be sure.

      Creating the ACL entries in code is trickier. (It's easy to do, but it's difficult to figure out how to do it). TBH, I've never done it. But at least the above will eliminate some of the drudgery.

      You've probably seen this, but for others trying to do the same thing: http://bobsguides.com/user-specific-pages.html.

      BTW, there's a whole other approach that doesn't involve the permissions system at all. You just make sure the user's username is at the beginning of the pagetitle and use a snippet to redirect any user whose username doesn't match. The down side of this is that, unlike what you're doing, it has no effect on Searches, Menus or getResources calls.

      I should also mention another method that works very well in some situations. If you add this line to the code above, just before the $doc->save() line, it will make the user the creator of their own page:

      $doc->set('createdby', $user->get('id'));


      That will allow you to use NewsPublisher, keep the users in the front end, and only allow them to edit their own resources: http://bobsguides.com/blog.html/2013/04/28/newspublisherrestricting-users-to-their-own-pages/. The users can just log in, go to their own page, and click on the "Edit" button to edit the page. They won't see the "Edit" button on anyone else's pages.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting