We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 3749
    • 24,544 Posts
    In Revo, users are just users. The permissions system determines whether they have access to the mgr (back end), web (front end + viewing resources in the Resource tree), or other contexts you create (same as web).

    Queries to get user info are somewhat ugly because the information for a single user is spread among several tables.
      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
      • 22303 MODX Staff
      • 10,725 Posts
      Quote from: BobRay at Mar 25, 2010, 10:04 PM

      Queries to get user info are somewhat ugly because the information for a single user is spread among several tables.
      I take offense to that. tongue

      And I hardly call these "queries" ugly:
      <?php
      $output = array();
      
      /* get the bobray user and his profile in a single query */
      $user = $modx->getObjectGraph('modUser', '{"Profile":{}}', array('username' => 'bobray'));
      
      /* get a userTpl chunk and pass the user and the core MODx profile attributes */
      $output[] = $modx->getChunk('userTpl', array_merge($user->toArray(), $user->Profile->toArray()));
      unset($user);
      
      /* get all users/profiles except bobray in a single query and loop through them */
      $users = $modx->getCollectionGraph('modUser', '{"Profile":{}}', array('username:!=' => 'bobray'));
      foreach ($users as $user) {
          /* get a userTpl chunk and pass the user and the core MODx profile attributes */
          $output[] = $modx->getChunk('userTpl', array_merge($user->toArray(), $user->Profile->toArray()));
      }
      return implode("\n", $output);
      ?>


      Add a custom table for your custom attributes and you can do:
      <?php
      /* get custom profile data, along with the modx user and profile data for bobray in a single query */
      $myProfile = $modx->getObjectGraph('myCustomProfileClass', '{"User":{"Profile":{}}}', array('User.username' => 'bobray'));
      
      /* dump all the attributes */
      var_dump(array_merge($myProfile->toArray(), $myProfile->User->toArray(), $myProfile->User->Profile->toArray()));
      ?>
        • 3749
        • 24,544 Posts
        LOL. I’m tempted to say it’s code only a mother could love. wink

        It *is* much nicer than the raw MySQL code it replaces, but I think I’d have to spend a few weeks (or months) learning JSON format to understand it, let alone figure out how to update user data the same way. The get*Graph() methods have always been a mystery to me.

        I could go for a few convenience methods that used that code and returned an array of user data or filled-out user objects , though. smiley

        Maybe they could be tacked onto the $modx->user object (or a subclass of that object -- we could call it ’modObeseUser’ smiley) as class methods.
          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
          • 22303 MODX Staff
          • 10,725 Posts
          Quote from: BobRay at Mar 25, 2010, 11:04 PM

          ...I think I’d have to spend a few weeks (or months) learning JSON format to understand it...
          You don’t have to use JSON to represent your "graph" of related objects to query at the same time (what the get*Graph() methods do); the methods accept a JSON string OR a PHP array, so these are the same without the scary JSON:
          <?php
          $user = $modx->getObjectGraph('modUser', array('Profile' => array()), array('username' => 'bobray'));
          $myProfile = $modx->getObjectGraph('myCustomProfileClass', array('User' => array('Profile' => array())), array('User.username' => 'bobray'));
          ?>


          Quote from: BobRay at Mar 25, 2010, 11:04 PM

          ...let alone figure out how to update user data the same way.
          These are the objects you are getting; now just set() a column value and save():
          <?php
          $myProfile = $modx->getObjectGraph('myCustomProfileClass', array('User' => array('Profile' => array())), array('User.username' => 'bobray'));
          $myProfile->set('shipping_address', '123 ABC Blvd');
          $myProfile->User->Profile->set('fullname', 'Bob Ray');
          $myProfile->save();
          ?>


          Quote from: BobRay at Mar 25, 2010, 11:04 PM

          I could go for a few convenience methods that used that code and returned an array of user data or filled-out user objects , though. smiley
          You have one on the modX class; and returning the data using $user->toArray() gives you an array; and $user->toJSON() gives you JSON, etc.

          Quote from: BobRay at Mar 25, 2010, 11:04 PM

          Maybe they could be tacked onto the $modx->user object (or a subclass of that object -- we could call it ’modObeseUser’ smiley) as class methods.
          The $modx->user already has access to his Profile:
          <?php
          $modx->user->getOne('Profile');
          var_dump($modx->user->Profile->toArray());
          ?>
            • 23491 ☆ A M B ☆
            • 1,056 Posts
            Quote from: allanb at Mar 22, 2010, 02:26 PM

            I am thinking of starting on a REVO version of WebloginPE. smiley

            Has anyone any thoughts or ideas on this huh

            Would you be interested in helping or joining such a project huh

            Interesting, was just thinking about this today! The opportunity for a web user solution definitely exists for Revo.

            Quote from: OpenGeek at Mar 26, 2010, 12:42 AM


            You don’t have to use JSON to represent your "graph" of related objects to query at the same time (what the get*Graph() methods do); the methods accept a JSON string OR a PHP array, so these are the same without the scary JSON [...]

            These are the objects you are getting; now just set() a column value and save():
            <?php
            $myProfile = $modx->getObjectGraph('myCustomProfileClass', array('User' => array('Profile' => array())), array('User.username' => 'bobray'));
            $myProfile->set('shipping_address', '123 ABC Blvd');
            $myProfile->User->Profile->set('fullname', 'Bob Ray');
            $myProfile->save();
            ?>



            Jason, the interoperability is just scary-cool. Especially if I’m in one of my JSON-for-everything moods wink

            I still have a lot of "dots" to connect to get from "my custom table" to "$modx->getObjectGraph(’myCustomProfileClass’, ’{"User":{"Profile":{}}}’, [...]", nevertheless I can’t wait. cool
              Mike Reid - www.pixelchutes.com
              MODx Ambassador / Contributor
              [Module] MultiMedia Manager / [Module] SiteSearch / [Snippet] DocPassword / [Plugin] EditArea / We support FoxyCart
              ________________________________
              Where every pixel matters.
              • 1169
              • 312 Posts
              Hi All

              Susan I understand what you are saying I think.

              Correct me if I an wrong.

              Using a setting-type table different users could have different fields in the table.

              From what bob says users are users

              By the looks of things we have 6 user tables 3 of these are user details modx_users, modx_users_attributes, modx_users_settings .
              Others are for system usage I suspect (realy not sure)

              If we need other fields these could be key’s in modx_users_settings
              or a new table possibly modx_users_attributes_extended or even simpler modx_users_extended or using OpenGeek’s terminology modx_users_custom or modx_users_custom_wlpe or even modx_users_wlpe_custom(thats enough).

              Could someone tell me if I am correct and advise best practice.
              I have read above posts many times.
              Please bear with me I’m new and not so young.

              I see the elegance of OpenGeeks code (just not shure I understand it. (if Bob is having trouble imagine my position in all this ))
              I suppose you don’t have to understand it to use it.
              The power of Objects is amazing.

              Is all the mapping of existing db’s already done. Looks like it to me by the code embarrassed
              Is this the mapping done by xPDOManager and xPDOGenerator.

              I will leave it at that. Hope I am not waisting your valuable time. I realy have tried reading the doc’s but without the grounding it’s not easy.

              The guys who wrote the doc’s are far advanced to many of us at the lower end of the food chain. One day the penny (cent) may drop.

              Thanks for all your support.
              Still not seen anyone offering to help with anything sad
              Allan
                DEVELOPMENT ENV:- Ubuntu 12.04 | MODx Revolution 2.2.8 | LAMP 2i Apache 2.2.22 | Php 5.3.10 | Mysql 5.5.31 MySQL client version: 5.5.31
                • 28042 ☆ A M B ☆
                • 24,524 Posts
                I was just replying about why Scotty chose to use a separate custom table, and not the web_user_settings table in Evo; I was not in any way referring to how Revo does things and the elegance of using xPDO. It’s like graphics design; I couldn’t design a paper bag to design my way out of, but I know a nice site design when I see one!
                  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
                  • 1169
                  • 312 Posts
                  Thanks Susan

                  Your insight and input is much appreciated.

                  Regards Allan.
                    DEVELOPMENT ENV:- Ubuntu 12.04 | MODx Revolution 2.2.8 | LAMP 2i Apache 2.2.22 | Php 5.3.10 | Mysql 5.5.31 MySQL client version: 5.5.31
                    • 3749
                    • 24,544 Posts
                    @OpenGeek, Great information. Thanks. After looking at the code some more, (and seeing the non-JSON version), I pretty much get it. I think "graph" in the name threw me. It is truly impressive how easily custom tables can be used to hydrate the objects.

                    A few more questions:

                    After this:
                    $user = $modx->getObjectGraph('modUser', array('Profile' => array()), array('username' => 'bobray'));


                    are the profile fields grafted onto the user object, or accessed indirectly?

                    $user->get('fullname'') // ??



                    And can they be updated via the $user object or do you need to explicitly get a profile object to update them?

                    Is the code above the equivalent of $user=getObject(’modUser’, etc.) followed by $user->getOne(’Profile’)?
                      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
                      • 22303 MODX Staff
                      • 10,725 Posts
                      Quote from: BobRay at Mar 26, 2010, 05:46 PM

                      After this:
                      $user = $modx->getObjectGraph('modUser', array('Profile' => array()), array('username' => 'bobray'));


                      are the profile fields grafted onto the user object, or accessed indirectly?

                      $user->get('fullname'') // ??

                      They are accessed indirectly via the hydrated related object, i.e.
                      $user->Profile->get('fullname');


                      Quote from: BobRay at Mar 26, 2010, 05:46 PM

                      And can they be updated via the $user object or do you need to explicitly get a profile object to update them?
                      When you call save on an object, any related objects that are loaded on that object (as the Profile is here) as also saved. So all you need to do is:
                      $user->set('username', 'newusername');
                      $user->Profile->set('fullname', 'New User');
                      $user->save();

                      and all your changes are saved in both the modUser and related modUserProfile rows.

                      Quote from: BobRay at Mar 26, 2010, 05:46 PM

                      Is the code above the equivalent of $user=getObject(’modUser’, etc.) followed by $user->getOne(’Profile’)?
                      Basically, except the get*Graph() methods are more efficient since they get everything in a single query. Using the getOne()/getMany() methods after a getObject/getCollection executes a separate query to populate the related objects. Also note that once you hydrate a specific related object (or set of objects) using either method, subsequent calls to getOne()/getMany() without a specific criteria specified should return the already hydrated related object( s ) with no additional queries.