We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 20196
    • 13 Posts
    Hi all

    I’ve been combing through the forums for a solution to my problem without any luck.

    I have the following problem;
    I want to do some of the work for my client seeing as none of them are very technical. So when ever my client creates a new modResouce, in a particular container, I want a plugin to create two symlinks for that resource and place them in two separate containers. The symlinks should have the same name as the resource as well as the same alias.

    Below is puny excuse for doing this myself however when ever I save a resource the manager hangs

    <?php
    $e = $modx->event->name;
    switch($e) {
        
    	case 'OnDocFormSave':
    		
    		//Referrence to the current Resource
    		$current = $modx->resource;
    		$serie = $current->getTVValue('serie');
    		$category = $current->getTVValue('category');
    	
    		//Should ensure that the user is doesn't create symlinks for anything other than resources in the right folder
    		if($current->getOne('ContentType')!='modResource'&&current->get('parent')==6)return;
    		
    		//Ensures that we don't create two new objects if the already exists 
    		$existingObjOne = $modx->getObject('modResource',array('pagetitle'=>$serie,'parent'=>symParentOne);
    		$existingObjTwo = $modx->getObject('modResource',array('pagetitle'=>$category,'parent'=>symParentTwo);
    
    		if($exsistingObjOne!=null||$exsistingObjTwo!=null)
    		{
    			return;
    		}
    		
    		
    		// use current resource tv.serie.value to locate parent folder for symlinks
    		$symParentOne = $modx->getObject('modResource',array('pagetitle' => $serie ));
    		$symIdOne = $symParentOne->get('id');	   
    		$symParentTwo = $modx->getObject('modResource',array('pagetitle' => $category ));
    		$symIdTwo = $symParentTwo->get('id');
    		
    
    		if($serie != null)
    		{
    			// Create symlink in series
    			$symOne = &$modx->newObject('modSymlink');
    			$symOne->set('pagetitle', $current->get('pagetitle'));
    			$symOne->set('parent',$symIdOne);
    			$symOne->set('published',1);
    			$symOne->set('symlink', $current->get('id'));
    			$symOne->save(); 
    		}
    		if($category != null)
    		{
    			// Create symlink in category
    			$symTwo = &$modx->newObject('?');
    			$symTwo->set('pagetitle', $current->get('pagetitle'));
    			$symTwo->set('parent',$symIdTwo);
    			$symTwo->set('published',1);
    			$symTwo->set('symlink',$current->get('id'));
    			$symTwo->save(); 
    		}
    		
    	break;
    
    	case 'OnDocFormDelete':
    		
    		//Referrence to the current Resource, get the name of the current resource for removing of symlinks
    		$current = $modx->resource;
    		//Should ensure that the user is doesn't delete symlinks for anything other than resources in the right folder
    		if($current->getOne('ContentType')!='modResource'&&current->get('parent')==6)return;
    
    		$symlinks = $modx->getCollection('modSymlink',array('pagetitle'=>$current->get('pagetitle')));
    		if($symlinks != null)
    		{
    			£symlinks->remove();
    		}
    		
    	break;
    }
    

    EDIT:
    Maybe I forgot some information so that you guys can help, i’m using MODx Revolution 2.0.8-pl (traditional) and what the code above is an attempt to create a plugin that automatically creates two symlinks wink

    Any help would be appreciated

    Best regards
    Moonkin

      • 20196
      • 13 Posts
      After sleeping on it I’m thinking that a TV with custom input type symlink also could be a way to do this.

      Again any help would be greatly appreciated.

      Best regards
      Moonkin
        • 3749
        • 24,544 Posts
        I think you were on the right track to begin with. Try creating a symlink in the Manager and looking at the fields in PhpMyAdmin (in the modx_site_content table).

        There is no symlink field. I think the ID goes in the content field and you’ll have to set the resource type appropriately.

        Also, I think it will be $modx->newObject(’modResource’); A symlink is just a modResource with the fields set a little differently.

        One more tip. Try doing it as a snippet first. It will be easier to debug because you’ll get PHP error messages.
          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
          • 20196
          • 13 Posts
          Thanks Bob I’ll continue with the plugin idea then, my reason for using "modSymlink" actually came from your guide, but I do recall someone saying something about using "modResource" instead. After throwing the code inside dreamweaver I also notice some errors in the syntax. I’ll post again once I’ve tryed it out.

          Best regards
          Moonkin
            • 3749
            • 24,544 Posts

            I was wrong, modSymlink is correct (though modResource would probably work). I think this code would handle the creation:

            <?php
            /* set these appropriately */
            
            $fields = array(
                'template' => 1, /* ID of desired template */
                'content_type' => 1, /* don't change this */
                'class_key' => 'modSymLink',
                'context_key' => 'web',
                'parent' => 12,  /* id of desired parent */
                'richtext' => 0,
                'hidemenu' => 0,
                'published' => 1,
                'searchable' => 0,
                'cacheable' => 1,
                'content' => 12,   // ID of linked resource
            );
            
            $resource = $modx->newObject('modSymlink', $fields);
            
            $resource->save();


              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
              • 20196
              • 13 Posts
              Hey bob and others

              I’ve been trying to figure out why this code doesn’t yield the desired effect.

              I did what Bob suggested and tried out the snippet idea, and while doing that it behaves exactly as expected. However when putting the whole thing together in a plugin the manager hangs and the symlinks aren’t created.

              This is the entire code of the plugin
              <?php
              $eventName = $modx->event->name;
              switch($eventName) 
              {
              	case 'OnDocFormSave':
              		
              		//Referrence to the current Resource
              		$current = $modx->resource;
              		$serie = $current->getTVValue('serie');
              		$category = $current->getTVValue('category');
              		
              		//$parentObject = $modx->getObject('modResource', array('pagetitle' => 'Pool', 'context_key' => $current->get('context_key') ));
              		
              		//Should ensure that the user is doesn't create symlinks for anything other than resources in the right folder
              		if($current->get('class_key')!='modDocument' && $current->get('parent')!= 6/*$parentObject->get('id')*/)
              		{
              			return;
              		}
              		
              		// use current resource tv.serie.value to locate parent folder for symlinks
              		$symParentOne = $modx->getObject('modResource',array('pagetitle' => $serie, 'context_key' => $current->get('context_key') ));   
              		$symParentTwo = $modx->getObject('modResource',array('pagetitle' => $category, 'context_key' => $current->get('context_key') ));
              		
              		//Ensures that we don't create two new objects if thye already exists
              		$existingObjOne = $modx->getObject('modResource',array('pagetitle'=>$current->get('pagetitle'),'parent'=>$symParentOne->get('id'),'context_key' => $current->get('context_key') ));
              		$existingObjTwo = $modx->getObject('modResource',array('pagetitle'=>$current->get('pagetitle'),'parent'=>$symParentTwo->get('id'),'context_key' => $current->get('context_key') ));
              		
              		if(!empty($existingObjOne)||!empty($existingObjTwo))
              		{
              			return;
              		}
              		
              		if(!empty($serie))
              		{
              			// Create symlink in serie
              			$fields = array(
              			'template' => 7, /* ID of desired template */
              			'content_type' => 1, /* don't change this */
              			'class_key' => 'modSymLink',
              			'context_key' => $current->get('context_key'),
              			'parent' => $symParentOne->get('id'),  /* id of desired parent */
              			'richtext' => 1,
              			'pagetitle' => $current->get('pagetitle'),
              			'hidemenu' => 0,
              			'published' => 1,
              			'searchable' => 0,
              			'cacheable' => 1,
              			'content' => $current->get('id')   // ID of linked resource
              			);
              			
              			$resource = $modx->newObject('modSymlink', $fields);
              			$resource->save(); 
              		}
              		if(!empty($category))
              		{
              			$fields = array(
              			'template' => 7, /* ID of desired template */
              			'content_type' => 1, /* don't change this */
              			'class_key' => 'modSymLink',
              			'context_key' => $current->get('context_key'),
              			'parent' => $symParentTwo->get('id'),  /* id of desired parent */
              			'richtext' => 0,
              			'pagetitle' => $current->get('pagetitle'),
              			'hidemenu' => 0,
              			'published' => 1,
              			'searchable' => 0,
              			'cacheable' => 1,
              			'content' => $current->get('id')   // ID of linked resource
              			);
              			
              			$resource = $modx->newObject('modSymlink', $fields);
              			$resource->save();
              		}
              		
              		break;
              
              	case 'OnDocFormDelete':
              		
              		//Referrence to the current Resource, get the name of the current resource for removing of symlinks
              		$current = $modx->resource;
              		//$parentObject = $modx->getObject('modResource', array('pagetitle' => 'Pool', 'context_key' => $current->get('context_key') ));
              		//Should ensure that the user is doesn't delete symlinks for anything other than resources in the right folder
              		if($current->get('class_key')!='modDocument'&& $current->get('parent')!= 6/*$parentObject->get('id')*/)
              		{
              			return;
              		}
              
              		$symlinks = $modx->getCollection('modSymlink',array('pagetitle'=>$current->get('pagetitle')));
              		if(!empty($symlinks))
              		{
              			$modx->removeCollection('modSymlink',array('pagetitle'=>$current->get('pagetitle')));
              		}
              		
              		break;
              }
              


              I have ensured that the plugin is listening for OnDocFormSave and OnDocFormDelete. I even tried putting the creation and deletion in separate snippets and just using the code for the plugin, manager still hangs and symlinks aren’t created.

              <?php
              $eventName = $modx->event->name;
              switch($eventName) 
              {
              	case 'OnDocFormSave':
              		
              		$modx->runSnippet('createSymlinks');
              		
              		break;
              
              	case 'OnDocFormDelete':
              		
              		$modx->runSnippet('deleteSymlinks');
              		
              		break;
              }
              


              Again any help would be greatly appreciated.

              Best regards
              Moonkin
                • 22303 MODX Staff
                • 10,725 Posts
                $modx->resource is only set in the front-end during Resource processing. You want $resource which is a reference to the modResource instance you are editing when OnDocFormSave is triggered.
                  • 20196
                  • 13 Posts
                  Just wanted to say that that did it so this issue can be considered solved.

                  This is the final plugin code:
                  <?php
                  $eventName = $modx->event->name;
                  switch($eventName) 
                  {
                  	case 'OnDocFormSave':
                  		
                  		//Referrence to the current Resource
                  		$current = $resource;
                  		$serie = $current->getTVValue('serie');
                  		$category = $current->getTVValue('category');
                  		
                  		//$parentObject = $modx->getObject('modResource', array('pagetitle' => 'Pool', 'context_key' => $current->get('context_key') ));
                  		echo 'class_key is:'. $current->get('class_key');
                  		echo 'parent is:'. $current->get('parent');
                  		//Should ensure that the user is doesn't create symlinks for anything other than resources in the right folder
                  		if($current->get('class_key')!='modDocument' || $current->get('parent')!= 6/*$parentObject->get('id')*/)
                  		{
                  			echo 'Symlinks NOT created, REASON: Resource is either not a modDocument or product not created in folder Pool';
                  			return;
                  		}
                  		
                  		// use current resource tv.serie.value to locate parent folder for symlinks
                  		$symParentOne = $modx->getObject('modResource',array('pagetitle' => $serie, 'context_key' => $current->get('context_key') ));   
                  		$symParentTwo = $modx->getObject('modResource',array('pagetitle' => $category, 'context_key' => $current->get('context_key') ));
                  		
                  		echo 'serie parent is:'. $symParentOne->get('pagetitle');
                  		echo 'category parent is:'. $symParentTwo->get('pagetitle');
                  		
                  		//Ensures that we don't create two new objects if thye already exists
                  		$existingObjOne = $modx->getObject('modResource',array('pagetitle'=>$current->get('pagetitle'),'parent'=>$symParentOne->get('id'),'context_key' => $current->get('context_key') ));
                  		$existingObjTwo = $modx->getObject('modResource',array('pagetitle'=>$current->get('pagetitle'),'parent'=>$symParentTwo->get('id'),'context_key' => $current->get('context_key') ));
                  		
                  		if(!empty($existingObjOne)||!empty($existingObjTwo))
                  		{
                  			echo 'Symlinks NOT created, REASON: They likely already exists';
                  			return;
                  		}
                  		
                  		if(!empty($serie))
                  		{
                  			echo 'Laver symlink';
                  			echo 'context_key is:'. $current->get('context_key');
                  			echo 'sym parent is:'. $symParentOne->get('id');
                  			echo 'pagetitle is:'. $current->get('pagetitle');
                  			echo 'content id is:'. $current->get('id');
                  			// Create symlink in serie
                  			$fields = array(
                  			'template' => 7, /* ID of desired template */
                  			'content_type' => 1, /* don't change this */
                  			'class_key' => 'modSymLink',
                  			'context_key' => $current->get('context_key'),
                  			'parent' => $symParentOne->get('id'),  /* id of desired parent */
                  			'richtext' => 1,
                  			'pagetitle' => $current->get('pagetitle'),
                  			'alias' => $current->get('pagetitle'),
                  			'hidemenu' => 0,
                  			'published' => 1,
                  			'searchable' => 0,
                  			'cacheable' => 1,
                  			'content' => $current->get('id')   // ID of linked resource
                  			);
                  			
                  			$resource = $modx->newObject('modSymlink', $fields);
                  			$resource->save(); 
                  		}
                  		if(!empty($category))
                  		{
                  			$fields = array(
                  			'template' => 7, /* ID of desired template */
                  			'content_type' => 1, /* don't change this */
                  			'class_key' => 'modSymLink',
                  			'context_key' => $current->get('context_key'),
                  			'parent' => $symParentTwo->get('id'),  /* id of desired parent */
                  			'richtext' => 0,
                  			'pagetitle' => $current->get('pagetitle'),
                  			'alias' => $current->get('pagetitle'),
                  			'hidemenu' => 0,
                  			'published' => 1,
                  			'searchable' => 0,
                  			'cacheable' => 1,
                  			'content' => $current->get('id')   // ID of linked resource
                  			);
                  			
                  			$resource = $modx->newObject('modSymlink', $fields);
                  			$resource->save();
                  		}
                  		
                  		break;
                  
                  	case 'OnDocFormDelete':
                  		
                  		//Referrence to the current Resource, get the name of the current resource for removing of symlinks
                  		$current = $resource;
                  		//$parentObject = $modx->getObject('modResource', array('pagetitle' => 'Pool', 'context_key' => $current->get('context_key') ));
                  		//Should ensure that the user is doesn't delete symlinks for anything other than resources in the right folder
                  		if($current->get('class_key')!='modDocument'|| $current->get('parent')!= 6/*$parentObject->get('id')*/)
                  		{
                  			return;
                  		}
                  
                  		$symlinks = $modx->getCollection('modSymlink',array('pagetitle'=>$current->get('pagetitle')));
                  		if(!empty($symlinks))
                  		{
                  			$modx->removeCollection('modSymlink',array('pagetitle'=>$current->get('pagetitle')));
                  		}
                  		
                  		break;
                  }
                  


                  Thanks to the both of you
                  Moonkin
                    • 3749
                    • 24,544 Posts
                    Looks good. If you don’t a suggestion ...

                    I’d advise changing

                    $current = $resource;


                    to

                    $current =& $resource;


                    in both places (or just use $resource since you’re not changing it). Otherwise, PHP will make a copy of the whole resource for no reason.


                      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
                      • 20196
                      • 13 Posts
                      Does getTVValue get all the values of a TV as an array?

                       $category = $resource->getTVValue('category'); 


                      And how do I iterate through this array creating a symlink for each of these values wink

                      I’m thinking something along the lines of this:

                      foreach($category as $key => $value)
                      			{
                      				
                      			}
                      


                      Thank you in advance