We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 29774
    • 386 Posts
    This is an auto-generated support/comment thread for Related.

    Use this forum to post any comments about this addition or any questions you have regarding its use.

    Brief Description:
    Create one-to-many and many-to-many relationships between MODx documents in the manager

    UPDATED: Related 1.0.3 released 16/06/2008
      Snippets: GoogleMap | FileDetails | Related Plugin: SSL
      • 29774
      • 386 Posts
      Another example - let’s say you need to categorise people by role.

      • Create a new folder called Roles
      • Create some documents under Roles, say one for ’Manager’, one for ’PA’, one for ’Partner’
      • Create a DropDown menu TV called Role and set the input values to:

      @EVAL return $modx->runSnippet('Related', array("parents"=>"20"));
      

      (Where 20 is the Id of the Roles folder).


      • Assign the Role TV to the Person template and you’re done.

      But what if you need to link some of the people to one or more other people? For example, some Managers might have one or more PAs.

      • Create a new checkboxes TV called PA with this for the input values
      @EVAL return $modx->runSnippet('Related', array("parents"=>"40","tag"=>"Role","tagData"=>"21"));
      

      (Where 40 is the document ID of the People folder and 21 is the ID of the PA role)


      • Assign the PA TV to the Person template and you now have a list of PAs that you can assign to each person.

        Snippets: GoogleMap | FileDetails | Related Plugin: SSL
        • 16545
        • 358 Posts
        This snippet does not work correctly for me, some errors & bugs, maybe because of my document structure (en-> catalogue -> category ->item)
        Ok, could you explane what is the difference between your magic snippet and a simple dropdown TV with "Input Option Value" like this one:

        @SELECT pagetitle FROM modx_site_content WHERE parent = ID - this one works without errors.

        where ID (is a ID of parent document)

        Some comments?
          • 29774
          • 386 Posts
          @labasus
          If you explain what you’re trying to do and show me the code you’re using, I’ll see if I can help. The snippet is working great for me. I too am using a deeply nested folder structure so that shouldn’t be an issue. Also let me know what versions of Ditto and Ultimateparent you have.

          It has these adavtanges over using an @SELECT:
          * You can generate a list based on a ’tag’ (ie the value assigned to a TV ). You’d need to do a join on three tables in your SQL statement to do this. You cannot currently do this with Ditto inside an @EVAL statement.
          * You can use tagData=’ultimateParent’ or = ’self’ and the snippet will use the ultimate parent ID or the ID of the document you are editing as the value to match to the tag. Note that if you’re using ’ultimateparent’ or ’self’ then *new* documents will default to INHERIT==@INHERIT - since the document needs to be saved first. This will make more sense if you recreate the second example I provided.
          * You can have child documents inherit the parent value(s).
          * You can format the list using the tpl paramater. For example, for one template I’m using the title field for a first name and the longtitle field for a surname. My template would be ||[+pagetitle+] [+longtitle+]==[+id+].
          * You can add a ’None’ option
          * In your example the list *values* would be the pagetitle rather than the ID of the document. Using IDs is preferable because if an administrator changes the pagetitle of a linked document then you’ve lost your relationship. Plus it should be quicker when outputting relationships to the website with Ditto since the id field is indexed.




            Snippets: GoogleMap | FileDetails | Related Plugin: SSL
            • 16545
            • 358 Posts
            First of all lets resolve errors that I have...

            Used ver. of snippets:
            Ditto ver. 2.1.0
            UltimateParent - tested with ver. 2.0 beta and 1.3

            Folder structure:
            en-catalogue(id80)-category-item1
            .....
            itemN
            ............
            categoryN-item1
            .....
            itemN
            Templates:
            1) catalogue - for catalogue document
            2) category - for category documents
            3) items - for items documents

            TV:
            catalogue (use "items" template) - dropdown,
            @EVAL return $modx->runSnippet('Related', array("parents"=>"80"));


            Then I’m entering into the any of "items" document, I’ve the same error (popup window) like this one below..., but the TV dropdown shows that have to show correctly.

            Popup window error: System Alert An error occurred while loading. Please see the event log for more information
            Log Event: Undefined index

            --------------
            Second:
            I’m trying to build up select form relative to the TV’s with EForm snippet:
            1) for responding forms
            2) sorting forms

            --------------
            Last stuff: You’ve done mistake in Snippet description
            @EVAL return $modx->runSnippet('Related', array("parents"=>"4");
            must be ->
            @EVAL return $modx->runSnippet('Related', array("parents"=>"4"));

              • 29774
              • 386 Posts
              @labasus

              I recreated your structure and when I edit an ’item’ page I get a menu listing the category pages - and no error. So I’m somewhat puzzled. Do you think you could attach a screenshot of the error? Perhaps I’m missing something.

              Thanks for pointing out those typos in the example text by the way, I’ve corrected the text.

              Regarding creating a dynamic select menu for an eform - I don’t think that’s going to work. Related is designed to be used in the backend Manager rather than the frontend, you would probably need to write your own snippet triggered by an eform event.

              Mark
                Snippets: GoogleMap | FileDetails | Related Plugin: SSL
                • 16545
                • 358 Posts
                I found the potential problem of this error. It’s a TV which was used in document template.

                TV details
                Name: kat
                Input Type: dropdown
                Input Option Values:
                @EVAL return $modx->runSnippet('Related',array("parents"=>"80"));


                Attached pixs can say more...

                Quote from: therebechips at Jun 16, 2008, 03:44 AM

                @labasus

                I recreated your structure and when I edit an ’item’ page I get a menu listing the category pages - and no error. So I’m somewhat puzzled. Do you think you could attach a screenshot of the error? Perhaps I’m missing something.

                Thanks for pointing out those typos in the example text by the way, I’ve corrected the text.

                Mark
                  • 29774
                  • 386 Posts
                  Hi Labasus, could you try three things please:

                  1. Try adding the parameter "topLevel"=>"1" and test.
                  (Remove this for the next two tests).

                  2. In related.php, please comment out this section:
                  	# loop through and assemble a list
                  	if (is_array($aFound) && count($aFound)>0) {
                  		for ($i=0; $i<count($aFound); $i++) {
                  			$aTagValues = explode(",",$aFound[$i][$tag]);
                  			for ($j=0; $j<count($aTagValues); $j++) {
                  				if ($aTagValues[$j] === $tagData || !$tagData) {	
                  					$fields = array('[+id+]','[+pagetitle+]','[+longtitle+]','[+introtext+]');
                  					$values = array($aFound[$i]["id"],$aFound[$i]["pagetitle"],$aFound[$i]["longtitle"],$aFound[$i]["introtext"]);
                  					$output .= str_replace($fields,$values,$rowTpl);
                  				}
                  			}
                  		}
                  	}
                  


                  3. In related.php, try replacing all the code with this:
                  <?php
                  return "option==value";
                  ?>
                  


                  Please try each one and test each time to see if you get the same error.

                  Cheers

                  Mark

                    Snippets: GoogleMap | FileDetails | Related Plugin: SSL
                    • 16545
                    • 358 Posts
                    Test results:
                    1) still have an error
                    2) without error, but blank dropdown (without any selection)
                    3) without error, dropdown selection with "value"

                    Just one thing I was missed: I’ve cut out some pice of structure, may be it could be helpful (pix attached)
                      • 29774
                      • 386 Posts
                      Hi Labaus,

                      could you please replace related.php with this code and let me know how you get on:

                      <?php
                      /*
                        Snippet name: Related
                        Created by: Mark Croxton ([email protected])
                        Last modified: 16/06/2008
                        Version: 1.0.2
                        Description: Create one-to-many and many-to-many relationships between MODx documents in the manager
                        Requires: Ditto 2.0+ and UltimateParent 1.0+
                      */
                      $output = '';
                      
                      # grab the current doc id, even if we're inside the manager
                      if(isset($_GET['id'])) {
                      	$id = intval($_GET['id']);
                      } else if (isset($modx->documentIdentifier)) {
                      	$id = $modx->documentIdentifier;
                      } else {
                      	$id = 0;
                      }
                      $parents = isset($parents)? $parents : 0;
                      $sortBy = isset($sortBy)? $sortBy : "pagetitle"; // pagetitle || longtitle || ID
                      $sortDir = isset($sortDir)? $sortDir : "ASC"; // ASC || DESC
                      $depth  = isset($depth)? $depth : 1; // Number of levels deep to retrieve documents
                      $display  = isset($display)? $display : "all"; // number of documents
                      $rowTpl = isset($tpl)?  $modx->getChunk($tpl) : '||[+pagetitle+]==[+id+]';
                      $tag = isset($tag)? "$tag" : "";
                      $topLevel = isset($topLevel)? "$topLevel" : 2;
                      $noneOption = isset($noneOption)? "$noneOption" : 0; // show 'None' option by default
                      $ultimateParent = $modx->runSnippet("UltimateParent", array("id"=>$id, "topLevel"=>$topLevel));
                      $inherit = isset($inherit)? "$inherit" : 0; // default: child documents with same template inherit selected parent's value
                      
                      $tagData = isset($tagData)? "$tagData" : 0; // default: use current doc id as tagged data
                      	
                      if ($tagData === "ultimateParent") {
                      	$tagData=$ultimateParent;
                      } else if ($tagData === "self") {
                      	$tagData=$id;
                      }
                      
                      # either a new document with ultimateParent=1 where we can't determine tagdata since id is not yet saved 
                      # or a child document where we specifically want to inherit the parent value
                      if (($ultimateParent != $id && $inherit) || (!$id && !$tagData)) { 
                      	$output = 'INHERIT==@INHERIT';
                      	return $output;
                      } else {
                      	# grab data using Ditto
                      	$modx->runSnippet('Ditto', 
                      		array(			
                      		"parents"		=>$parents,
                      		"depth"			=>$depth,
                      		"display" 		=>$display,
                      		"sortBy"		=>$sortBy,
                      		"sortDir"		=>$sortDir,
                      		"save"			=>"2",
                      		"tpl"			=>"@CODE [+id+][+pagetitle+][+longtitle+][+introtext+][+".$tag."+]"
                      		)
                      	);
                      	$aFound  = $modx->getPlaceholder("ditto_resource");
                      
                      	$fields = array('[+id+]','[+pagetitle+]','[+longtitle+]','[+introtext+]');
                      	
                      	# loop through and assemble a list
                      	if (is_array($aFound) && count($aFound)>0) {
                      		for ($i=0; $i<count($aFound); $i++) {		
                      			$aTagValues = array();
                      			if ($tag !='') {
                      				$aTagValues = explode(",",$aFound[$i][$tag]);
                      			}
                      			if (count($aTagValues)>0) {
                      				for ($j=0; $j<count($aTagValues); $j++) {
                      					if ($aTagValues[$j] === $tagData) {	
                      						$values = array($aFound[$i]["id"],$aFound[$i]["pagetitle"],$aFound[$i]["longtitle"],$aFound[$i]["introtext"]);
                      						$output .= str_replace($fields,$values,$rowTpl);
                      					}
                      				}
                      			} else {
                      				$values = array($aFound[$i]["id"],$aFound[$i]["pagetitle"],$aFound[$i]["longtitle"],$aFound[$i]["introtext"]);
                      				$output .= str_replace($fields,$values,$rowTpl);
                      			}
                      		}
                      	}
                      	# none option
                      	if ($noneOption) {
                      		$output = 'None==0'.$output;
                      	} else {
                      		$output = substr($output,2);
                      	}
                      	return $output;	
                      }
                      ?>
                      


                      Also please ensure that the snippet code is included exactly like this:
                      <?php
                      return include($modx->config['base_path'] . 'assets/snippets/related.php');
                      ?>
                      


                      Many thanks

                      Mark
                        Snippets: GoogleMap | FileDetails | Related Plugin: SSL