We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 44580
    • 189 Posts
    I am about to start building a website that will report on a child's progress as they learn how to play tennis. As such, any one of: the child, their parent(s) or their coach can log into the site and see the following information:

    Coach: a list of all the parents and their children that they coach. They can drill down this list until they get to the attributes of a specific child.
    Parent: a list of all their children being coached from which they could drill down to the attributes of a specific child.
    Child: all the attributes for themselves.

    I therefore need a hierarchical relationship between coaches, parents and children. I would like to create and maintain this hierarchy using Modx users and I would like to use the Login extra to authenticate to the site. That is about as far as I have got. From my research, I have not been able to determine how to create the relationships between users such that the content presented can be varied.

    Some additional information:
    - all users will be created by the site manager (the owner of the business)
    - the site manager must be able to create and maintain the relationships between users

    If anyone out there can help with some ideas, I would be most appreciative.
    • You would then want to extend the exiting moduser, take a look here for more information on extending. That should get you going in the right direction.

      Cheers
        Evo Revo // Ubuntu, CentOS, Win // Apache 2x, Lighttp (Lighty)
        Visit CharlesMx.com for latest news and status updates.
      • I would be inclined to more-or-less bypass the usual user validation system, using something along these lines instead, based perhaps on TVs or the Tree structure itself

        http://bobsguides.com/blog.html/2013/05/22/protecting-pages-the-easy-way/
          Studying MODX in the desert - http://sottwell.com
          Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
          Join the Slack Community - http://modx.org
          • 44580
          • 189 Posts
          Thank you for the quick replies.

          @CharlesMx: I can see how that would be useful for extending an individual user, but not so much for building relationships (one to one / one-to-many) between users.
          @sottwell: I was hoping to use Modx's manager for not only creating and maintaining the users, but also the relationships between users.

          It's not so much about protecting resources from unauthorized users, but more about traversing down the tree to get to the correct destination. For example, Coach A would log in, and be presented with a list of all parents and children that he/she coaches. Upon selecting Child B, the details for that child would be displayed for updating. If he'd selected Child F instead, those details would be displayed. Note that the fields will always be the same but the data will vary.

          I'm not a PHP coder - my background is databases and SQL, so my first tendency is to step outside moduser and create my own user tables. But I want to avoid re-inventing the wheel. Perhaps I'm just not seeing the answer that's in front of me. If that's the case then some further explanation would be appreciated.
            • 3749
            • 24,544 Posts
            I don't see any way to do this properly without some custom code, especially since there are many-to-many relationships involved (e.g., parents with more than child and children with more than one parent).

            It's conceivable that you could create child, coach, parent, childParent, coachParent, and childCoach tables, and then use something like RowBoat to handle the CRUD tasks and FormIt or UpdateProfile for the UI, but I'm not sure it would work.

            Without the many-to-many relationships, it might be possible to create a Resource for each parent, child, and coach with TV's for the relationships (e.g., a child's page would have a ParentID TV and a CoachId TV). Then you might be able to use getResources and FormIt or UpdateProfile to handle the data, but it would be difficult, inefficient, and slow as well as difficult to maintain.

            Even with the many-to-many relationships, the TV method could work with comma-separated lists in the TV value but it would be difficult to maintain and the searching and sorting would require some custom code.
              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
              • 44580
              • 189 Posts
              Thanks BobRay, I was kinda coming to the same conclusion. In order to try and keep it simple, I'm thinking of something like this:

              • Create three groups: coaches, parents and children
              • As users are created, add them to the appropriate group
              • Use this group membership to direct logins to the appropriate landing page
              • The landing page for the coach would provide a selection list of all children being taught by that coach (coaches don't need to act upon parent data)
              • The landing page for the parent would provide a selection list of each child (or go straight to the child landing page if only one)
              • The landing page for the child would be the child details page

              I could then maintain separate coach, parent and child master/detail tables (that includes the relationship between each) and use these to build the selection lists for coach and parents. All the other detail pertaining to the children's progress would be contained in external tables also.

              Use xPDO (and your excellent tutorial) to integrate these external tables into Modx. That should get me most of the way with one major flaw: users would have to be maintained in two separate places - Modx manager and some custom pages I'd have to build to maintain the relationships. This is not ideal, but I may be able to sell it to the customer (who will be the one adding and maintaining users).

              Do you think this could work without too much custom code? I admit to finding the whole exercise somewhat daunting and probably would not be taking it on except that the customer is my son smiley.
                • 3749
                • 24,544 Posts
                I can think of about 10 different ways to do this and I'm not really sure which one would be best for your use case. I think if you do it right, you shouldn't have to maintain things in two separate places.

                It's hard to estimate the amount of custom code you'd have to do without knowing the final design. It would be a fair amount unless you extend the modUserProfile object, (and maybe the modUser object as well) which I think is not all that difficult (though I've never done it). Then I think you might be able to use the various parts of the Login and Peoples packages for much of it.

                I think Profile and UpdateProfile are fairly flexible and both take preHooks and postHooks so it should be possible to create a custom form for each type of "user" and a small amount of custom code to do the CRUD work in the preHooks and PostHooks.

                Another way to go would be to add fields to the Create/Edit User panel and you could use a plugin attached to OnUserFormPrerender and OnUserFormSave to handle the data.

                I think I would not use master/detail tables for the relationships, but rather intersect objects (childParent, childCoach, etc.) where each record contains, for example a coach ID and a child ID. Take a look at the modResourceGroupResource, modTemplateVarTemplate, modUserGroupMember, etc. objects here:
                http://bobsguides.com/modx-object-quick-reference.html. xPDO is fantastic at handling that kind of setup. It allows you to do things like this:

                $coach->getMany('Children');
                $parent->getMany('Children');
                $child->getMany('Parents');
                $child->getOne('Coach');
                // or if a child can have more than one coach:
                $child->getMany('Coaches');
                
                


                You might also look at MIGX and MIGXDB for your UI.

                  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
                  • 44580
                  • 189 Posts
                  Wow. Thanks BobRay and others for all the great ideas. I have some researching to do! Perhaps, as I get further into the design, I might have some more questions and if I do I might trouble you some more.
                    • 44580
                    • 189 Posts
                    Having given all the good ideas some further thought, I have come up with a possible approach:

                    • Extend ModUser by adding two additional columns: Coach and Parent. This is based on the realization that (for this app) a child can have one and only one parent, and one and only one coach. These columns would only contain data for a Children record, and would be empty for Parent and Coach records
                    • Create user groups to define the type of user; ie coaches_ug, parents_ug and child_ug. This will be used to determine the landing page (I have this working already)
                    • Use rowboat to build the list of children on the Parents and Coaches landing pages

                    I still have a couple of very grey areas that I'm hoping someone has experience with:

                    Q1. If I extend Moduser how are these extra columns maintained? Are they automatically added to the Manage Users form? If not automatic, can they be manually added and if so how? (yes, I know that was 4 questions)

                    Q2. Assuming my extra columns have been added to the Manage Users form, I want to ensure that only existing Coaches and/ or Parents can be added. This means that the input type for these columns would need to be a drop down list that contained username values based on the user groups coaches_ug and parents_ug, but would need to write back ids. Can this be done and if so how?
                      • 3749
                      • 24,544 Posts
                      I think people usually extend modUserProfile rather than modUser, since it already has many of the fields you'll be using (phone, email, etc.).

                      One thing to consider if there's a way to make it work is to just co-opt some unused fields of the user profile (e.g., fax, comment, etc.). You have to be careful of the size and type of the field, but if you don't have too many custom fields it can keep you from having to extend anything.

                      Q1. Usually the extra fields are in a whole new table. It's strongly recommended that you not modify the default MODX tables. You have to create them, usually in PhpMyAdmin.

                      Q2. The MODX convention is to generate the drop-down list from a string in this form and only store the IDs:

                      Coach1==1||Coach2==2||Coach3==3


                      There are lots of different ways to handle storing that result. One is to use a TV for the drop-down and a plugin or snippet to store the value.

                      Have you looked at MIGX and MIGXdb? I've never used them for anything but it's possible you could do the whole thing with them and not have to create any custom code or extend any objects.



                        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