We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22303 MODX Staff
    • 10,725 Posts
    Quote from: Everett at Nov 23, 2010, 05:01 PM

    It’s similar to the problems with table- vs. CSS-layouts. Everyone says table layouts are horrible, and to be fair, table soup sucks... but div soup is no better. ORMs are great... but I’d rather write SQL joins than navigate through relations in an (unfamiliar) ORM layer. Having some methods that return an entire object with all related fields would spare developers the trouble of having to manually map out the relations. It’s also more useful to have an abstraction here: if I can return *entire* objects using one method, regardless of which objects are being operated on, then I can re-use a lot of code. More and more I end up passing around fully qualified objects as my "units". You know?
    Hmmm, not sure I agree here on the why (though I still think the methods useful). I just think blind usage of these methods is a problem. Loading an entire graph of objects is a very memory intensive operation, especially when dealing with larger collections, and to use the excuse of I don’t want to have to know the names of the relation aliases so I just load everything scares the shit out of me, tbh. Like, end of the world is closer than ever scary.

    I think maybe you have drank too much of the NoSQL kool-aid and read one-too-many O/RM-to-Vietnam comparison, but I could be wrong (or biased). laugh
      • 9207 ☆ A M B ☆
      • 2,475 Posts
      Yeah... I know it could be playing with fire and it could be abused. The methods are still useful. I don’t think I’d use that on a collection, but certainly on an object, esp. if it could lazily load the related attributes. No-SQL really sucks at times (e.g. when normalizing object formats), but the ability to retrieve the whole object with all related fields is hugely powerful.

      If it helps make the case for a more legitimate use-case, I’m trying to develop PHP interfaces for dealing with arbitrary objects, so it’s really important to have a set of functions that perform similar tasks on arbitrary objects.
        • 3749
        • 24,544 Posts
        getObjectGraph() and getCollectionGraph() will let you get an object or a group of objects and their related objects in a single query. You do have to know the names of the related objects, but they’re pretty intuitive (e.g., Parents, Children, CreatedBy, etc.). It’s *way* more efficient to get just what you need at the moment. A resource has a crapload of heavy related objects (ancestor resource objects, child resource objects, TV objects, a template object, a bunch of related user objects, and user group objects -- which have their own related user objects, for example) and it’s unlikely that you’d need very many of them for a given operation.

        Here’s an example of getCollectionGraph() for users and profiles:

        $users = $modx->getCollectionGraph('modUser', array('Profile' => array()), array('active' => '1'));
        
        foreach($users as $user) {
          $output .= 'USER: ' . $user->get('username') . '<br />';
          $output .= 'FULLNAME: ' . $user->Profile->get('fullname') . '<br /><br />';
        }
        return $output;
        
          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
          • 9207 ☆ A M B ☆
          • 2,475 Posts
          Thanks, Bob. That looks interesting, but unfortunately I don’t think it’d fulfill my need to code to a particular interface. Is there a simple way to programmatically iterate through all relations? The problem is that I may not know what the various relations or attributes are. That’s one reason why the "toArray" is so useful... it doesn’t care what the attributes are, it just gets all of them.
            • 3749
            • 24,544 Posts
            Quote from: Everett at Nov 24, 2010, 09:49 AM

            Thanks, Bob. That looks interesting, but unfortunately I don’t think it’d fulfill my need to code to a particular interface. Is there a simple way to programmatically iterate through all relations? The problem is that I may not know what the various relations or attributes are. That’s one reason why the "toArray" is so useful... it doesn’t care what the attributes are, it just gets all of them.

            This member variable is in the abstract xPDOObject class:
            public $_relatedObjects= array ();


            I don’t know if it’s actually set anywhere. I suspect that it’s available to store related objects during processing, so it probably doesn’t do what you want.

            I guess you could parse the schema file and get them on your own. Or you could get the metadata from the DB and try to collect them from that.
              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
              You can use xPDO::getAggregates() and xPDO::getComposites() to get the relationship metadata for any class.

              xPDOObject::_relatedObjects stores the related instances that are actually loaded in memory for a specific xPDOObject instance.

              With the proposed methods (xPDO::getGraph() and xPDOObject::toArrayGraph()), we will likely make use of all of these methods in order to provide options to traverse an entire graph of related objects, only the parts of the graph that are already loaded, just composites, just aggregates, etc.
                • 3749
                • 24,544 Posts
                Nice.

                BTW, isn’t this a bit oxymoronic with respect to naming conventions? wink

                public $_relatedObjects= array ();
                  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 Nov 24, 2010, 04:09 PM

                  Nice.

                  BTW, isn’t this a bit oxymoronic with respect to naming conventions? wink

                  public $_relatedObjects= array ();

                  Thanks for pointing this out actually...

                  If you follow PEAR standards maybe, but using this technique here allows me to avoid using up class member names that might actually be column names in a table and therefore might need to be aliased as an object member (i.e. xPDO::OPT_HYDRATE_FIELDS is set to true). And tbh, I really wanted it to be protected, IOW, I wanted other core classes in the core of the framework to be able to access this data directly without making it public, but this is not possible in PHP since there is no concept of a package to provide protected access to. All protected gets you in PHP is access in derivative classes, and this leads to many inaccuracies in the intentions of the code here. I will say that a general rule of thumb is if it is public and starts with an _, then it is likely intended to be protected; IOW it should only be directly accessed from classes in the package which in this case is the core om package. Of course, this is not always the case. For example, public static _loadInstance is now intended to be public, it just started out as private in code that is used in MODx and needs to be aliased as loadInstance() while _loadInstance() is deprecated for a release or two.

                  Regardless, this is something I can address in documentation for clarification, and in code via consistency to that documentation.

                  So no, it is done on purpose, so it can be accessed from other classes in the package; it is protected at heart. The _ naming convention == private thing IMO is an arbitrary barrier placed on implementation (leftover from when PHP had no concept of method/member scope); arbitrary in that prevents the full-potential of practical PHP applications from being realized in some cases in trade for ideals.
                    • 3749
                    • 24,544 Posts
                    That makes perfect sense. I’ve always considered the $_variable naming convention as simply a reminder that the variable is not meant to be accessed casually from outside the class and it sounds like that’s how it’s being used. I generally provide a get() method for them if they’re needed from outside the class although that would probably create performance issues if done consistently in the core 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