We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 5160
    • 118 Posts
    I have a client who wants a private area on their website in which to show project status information to a selection of customers. The information is unique to each customer and should not be seen publicly or by other customers who have logged in. The customers do not need to edit or add to the information and customers will be added to the system by the client, no signup form is required.

    My current thought on how to achieve this without writing a custom solution is:

    - Create a TV called allowedUserName
    - Create a resource called Private, add child resources for each customer to hold the private information in the *content field and manually add the allowedUserName TV value for each resource.

    So the resource tree would look like:

    - Private
    ----Customer 1 (allowedUserName = jim)
    ----Customer 2 - (allowedUserName = bob)
    ----...

    - Create a user group called Customers
    - Add Customer users to the system via MODX Manager
    - Restrict access to the Private resource to members of the Customers user group
    - Use the Login addon by Splittingred to allow Customers to login and direct them to the Private resource
    - Add a call to getResources on the Private resource to list the *content field of children with tvFilters set to: allowedUserName==[[+modx.user.username]]

    This is not a high traffic site, if my client gets 20 customers a year he’s doing well so caching isn’t critical and there won’t be many child resources. I know I would need to be careful that Private Child Resources didn’t show in Wayfinder calls etc. but is there anything that stands out as stupid here? Is there an existing Extra that would provide this functionality?

    Thanks,

    Chris

    This question has been answered by BobRay. See the first response.

    [ed. note: chris.dempsey78 last edited this post 12 years, 10 months ago.]
    • discuss.answer
      • 3749
      • 24,544 Posts
      Rather than messing with all the user groups, resource groups, and ACL entries, I would be tempted to just put the users all in a user group called AllowPrivate and put this snippet at the top of the page template or in the page content:


      [[!AllowPrivate]]



      <?php 
      /* AllowPrivate snippet */
      
      if ($modx->user->isMember('AllowPrivate')) {
         return '';
      } else {
          $loginPageId = 12; /* replace with ID of your login page, or some other page */
          $url = $modx->makeUrl($loginPageId, "", "", "full");
          $modx->sendRedirect($url);
      }


      More info here: http://bobsguides.com/blog.html/2013/05/22/protecting-pages-the-easy-way/
        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
        • 5160
        • 118 Posts
        Appreciate the reply, my apologies for the slow response.

        Your suggested snippet should slim down the code involved nicely, thank you.

        It wasn't sitting comfortably in my head using getResources to loop through all the child resources of the Private container so I'll use a custom snippet instead:
        <?php
        
        $user = $modx->getUser();
        $username =  $user->get('username');
        
        $c = $modx->newQuery('modResource');
        $c->innerJoin('modTemplateVarResource','TemplateVarResources');
        $c->innerJoin('modTemplateVar','TemplateVar','`TemplateVar`.`id` = `TemplateVarResources`.`tmplvarid` AND `TemplateVar`.`name` = "allowUsername"');
        
        $c->where(array(
            'parent:IN' => array(21),
            'deleted' => false,
            'published' => true,
            'TemplateVarResources.value:=' => $username,
        ));
        
        $resources = $modx->getCollection('modResource',$c);
        
        $output = '';
        
        foreach ($resources as $resource) {
            $output .= 'Here is your private content:<br/>';
        	$output .= $resource->get('content');
        }