We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26503
    • 620 Posts
    I have a schema for some custom tables:

    (lots of rows removed for readability)

    <?xml version="1.0" encoding="UTF-8"?>
    <model package="extdata" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
    
    	<!-- artist table definition related -->
    	<object class="ArtistAttributes" table="artist_attributes" extends="xPDOSimpleObject">
    		<field key="userkey" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="" />
    		<!-- a bunch of fields -->
    		<composite alias="ArtistDiscography" class="ArtistDiscography" local="id" foreign="artistkey" cardinality="many" owner="local" />
    		<composite alias="ArtistGenremap" class="ArtistGenremap" local="id" foreign="artistkey" cardinality="many" owner="local" />
    		<composite alias="ArtistGigs" class="ArtistGigs" local="id" foreign="artistkey" cardinality="many" owner="local" />		
    		<composite alias="ArtistAudio" class="ArtistAudio" local="id" foreign="artistkey" cardinality="many" owner="local" />		
    		<composite alias="ArtistMedia" class="ArtistMedia" local="id" foreign="artistkey" cardinality="many" owner="local" />		
    		<composite alias="ArtistsManagers" class="ArtistsManagers" local="id" foreign="artistkey" cardinality="many" owner="local" />		
    	</object>
    	
    	<!-- an artist may belong to many genres -->
    	<object class="ArtistGenremap" table="artist_genremap" extends="xPDOSimpleObject">
    		<field key="artistkey" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
    		<field key="genreskey" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
    		<aggregate alias="ArtistAttributes" class="ArtistAttributes" local="artistkey" foreign="id" cardinality="one" owner="foreign" />
    		<aggregate alias="ArtistGenres" class="ArtistGenres" local="genreskey" foreign="id" cardinality="one" owner="foreign" />
    	</object>
    	
    	<!-- list of genre names -->
    	<object class="ArtistGenres" table="artist_genres" extends="xPDOSimpleObject">
    		<field key="genre" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
    		<aggregate alias="ArtistGenremap" class="ArtistGenremap" local="id" foreign="genreskey" cardinality="many" owner="local" />		
    	</object>
    	
    	<!-- artist mp3s an artist may have many mp3 instances -->
    	<object class="ArtistAudio" table="artist_audio" extends="xPDOSimpleObject">
    		<aggregate alias="ArtistAttributes" class="ArtistAttributes" local="artistkey" foreign="id" cardinality="one" owner="foreign" />
    	</object>
    	
    	<!-- an artist may have many albums -->	
    	<object class="ArtistDiscography" table="artist_discography" extends="xPDOSimpleObject">
    		<aggregate alias="ArtistAttributes" class="ArtistAttributes" local="artistkey" foreign="id" cardinality="one" owner="foreign" />
    	</object>
    	
    	<!-- artist media an artist may have many media instances -->
    	<object class="ArtistMedia" table="artist_media" extends="xPDOSimpleObject">
    		<aggregate alias="ArtistAttributes" class="ArtistAttributes" local="artistkey" foreign="id" cardinality="one" owner="foreign" />
    		<aggregate alias="ArtistMediatypes" class="ArtistMediatypes" local="mediatypekey" foreign="id" cardinality="one" owner="foreign" />
    	</object>
    	
    	<!-- list of media types -->
    	<object class="ArtistMediatypes" table="artist_mediatypes" extends="xPDOSimpleObject">
    		<aggregate alias="ArtistMedia" class="ArtistMedia" local="id" foreign="artistkey" cardinality="many" owner="local" />
    	</object>
    	
    	<!-- artist gigs - an artist may have many gigs -->
    	<object class="ArtistGigs" table="artist_gigs" extends="xPDOSimpleObject">
    		<aggregate alias="ArtistAttributes" class="ArtistAttributes" local="artistkey" foreign="id" cardinality="one" owner="foreign" />
    	</object>
    	
    	<!-- manager info a manager may belong to many artists -->
    	<object class="ArtistsManagers" table="artists_managers" extends="xPDOSimpleObject">
    		<aggregate alias="ArtistAttributes" class="ArtistAttributes" local="artistkey" foreign="id" cardinality="one" owner="foreign" />
    	</object>
    	
    	
    </model>



    And I am trying to get a list of genres that a particular artist belongs to, the genremap table just maps artist ids to genre ids in the genre's table [which just contains the genre name & an id]


    So, it seems to me that I should be able to retrieve a list of genre names that a particular artist belongs to from the artist object:

    $artist = $this->modx->getObject('ArtistAttributes', array('userkey'=>$id));
    


    Is this possible? Once I grab the artist object, aren't the genre names that artist belongs to in that object because of the ay the tables are related?

    If so, how?


    If not, I was working on trying to query the tables and not getting far, how can I make this work? [how can I grab a list of genre names that particular artist belongs to?]

    $query = $modx->newQuery('ArtistGenremap');
    		
    		$query->select($modx->getSelectColumns('ArtistGenremap','ArtistGenremap','',array('id','genreskey','artistkey')));
    		$query->select(array(
    		  'ArtistGenres.genreskey'
    		));
    		$query->where(array('artistkey' => $aid));
    		
    		$query->leftJoin('ArtistGenres','ArtistGenres');
    		
    		$genres = $modx->getCollection('ArtistGenremap',$query);
    		
    		
    		
    		foreach($genres as $genre){
    			//echo $genre->get('id').'
    ';
    			echo $genre->get('genreskey').'
    ';
    			echo $genre->get('artistkey').'
    ';
    			echo $genre->get('genre').'
    ';
    			echo '
    
    
    
    ';
    			
    		}
    


    That does not work, what am I doing wrong?

    -thanks
    -sean
      *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

      Sean Kimball CLP, CLS.
      Technical Director / Sr. Developer | BigBlock Studios
      ._______________________________________________.
      Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
      27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
      phone/fax: 905-426-5525
      • 26503
      • 620 Posts
      Got the query working, though I can't seem to use/assign an alias, I'm guessing that the alias needs to be assigned in the model?

      Works:

      // get artist genres
      		$query = $modx->newQuery('ArtistGenremap');
      		$query->leftJoin('ArtistGenres','ArtistGenres');
      		$query->select('ArtistGenremap.*,ArtistGenres.*');
      		$query->where(array('ArtistGenremap.artistkey' => $aid));
      		$genres = $modx->getCollection('ArtistGenremap',$query);
      		
      		
      		foreach($genres as $genre){
      			//echo $genre->get('id').'<br>';
      			echo $genre->get('genreskey').'<br>';
      			echo $genre->get('artistkey').'<br>';
      			echo $genre->get('genre').'<br>';
      		}
      



      Doesn't work:

      // get artist genres
      		$query = $modx->newQuery('ArtistGenremap');
      		$query->leftJoin('ArtistGenres','AG');
      		$query->select('ArtistGenremap.*,AG.*');
      		$query->where(array('ArtistGenremap.artistkey' => $aid));
      		$genres = $modx->getCollection('ArtistGenremap',$query);
      		
      		
      		foreach($genres as $genre){
      			//echo $genre->get('id').'<br>';
      			echo $genre->get('genreskey').'<br>';
      			echo $genre->get('artistkey').'<br>';
      			echo $genre->get('AG.genre').'<br>';
      		}
      


      Would still be interested if this data is 'just available' to me from the $artist object...
        *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

        Sean Kimball CLP, CLS.
        Technical Director / Sr. Developer | BigBlock Studios
        ._______________________________________________.
        Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
        27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
        phone/fax: 905-426-5525
        • 22303 MODX Staff
        • 10,725 Posts
        Use the getCollectionGraph method to get it all in one query...

        <?php
        $genreMaps = $modx->getCollectionGraph('ArtistGenremap', array('ArtistGenres'=>array()), array('artistkey' => $aid));
        foreach ($genreMaps as $genreMap) {
            echo $genreMap->ArtistGenres->get('genre');
        }
        


        FWIW, I think ArtistGenres in your model should be singular, i.e. ArtistGenre, for what it's worth. I generally make my class names singular (since an object represents a table row) and my table names themselves plural (since they represent a table of rows).
          • 26503
          • 620 Posts
          Hmmm can I use the getCollectionGraph to retrieve ALL the artist data in one go?

          Trying to sort it out through the docs, not having much luck though... sad
            *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

            Sean Kimball CLP, CLS.
            Technical Director / Sr. Developer | BigBlock Studios
            ._______________________________________________.
            Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
            27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
            phone/fax: 905-426-5525
            • 3749
            • 24,544 Posts
            If you leave out the third argument to getCollectionGraph, you should get all of the existing records.


            ------------------------------------------------------------------------------------------
            PLEASE, PLEASE specify the version of MODX you are using.
            MODX info for everyone: http://bobsguides.com/modx.html
              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
              • 26503
              • 620 Posts
              Hi Bob,

              sorry, no I mean all the data for a single artist, i.e. an artist has gigs, media, a manager..etc..etc.. everything in the model is related somehow, so is it possible to get all of it at once?

              also, is there a way to view that data easily, if I just try to print_r($artist) I get all the modx stuff as well, it would be handy to be able to dump it from time to time & see what I have got...

              Seems to me that I should be able to do something like this:
              $artist = $modx->getCollectionGraph('ArtistAttributes', '{"ArtistAudio":{},"ArtistMedia":{},"ArtistGigs":{},"ArtistsManagers":{},"ArtistGenremap":{"ArtistGenres":{}}}', array('ArtistAttributes.id'=>84));	
              


              to grab a single artist & all their related data, but even testing with something like this:

              $artist = $modx->getCollectionGraph('ArtistAttributes', '{"ArtistAudio":{}}', array('ArtistAttributes.id'=>84));
              
              foreach ($artist->getMany('ArtistAudio') as $media) {
                 
              	echo $media->get('label') . " <br>";
                 
              }
              


              Gives me a non-object error... I'm missing something here... [ed. note: sean69 last edited this post 14 years, 5 months ago.]
                *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

                Sean Kimball CLP, CLS.
                Technical Director / Sr. Developer | BigBlock Studios
                ._______________________________________________.
                Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
                27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
                phone/fax: 905-426-5525
                • 22303 MODX Staff
                • 10,725 Posts
                You want getObjectGraph() there. getCollectionGraph returns an array of xPDOObjects.

                All xPDOObjects have a toArray() method which you can use to inspect the field data without all the other information getting in the way. It also can directly render an array representing a graph of related objects, e.g.

                <?php
                $artist = $modx->getObjectGraph('ArtistAttributes', '{"ArtistAudio":{}}', array('ArtistAttributes.id' => 84));
                var_dump($artist->toArray('', false, false, true));
                


                Note that the includeRelated parameter of the toArray() method can also be a graph itself which would be automatically loaded. Passing true, as in the scenario above, simply includes any already loaded related objects.