We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 3496
    • 101 Posts
    I don’t know whether other people would be interested in this - and it’s probably not tested thoroughly enough (for example: no testing with resourceGroups done yet), but see attachment for an alpha version of a DocumentBuilder class.

    It works more or less the same as the Evolution DocumentManager include class (0.5.3b), but is meant for use in MODx Revolution.

    Any comment is welcome.
    Some questions I have:

    • Is this useful for other people?
    • Should I make this into an offical package? (or is that overkill for an include file)
    • Where in the directory structure should an include file be located? (currently: core/components/docbuilder)
    • How should I call the class? (current name: modDocumentBuilder)
    • Is my approach to error-handling ok? (yeah, I probably should use lexicon more)
    (I’m not that experienced in PHP and MODx yet, so forgive me if I made any stupid mistakes)

    Furthermore: any help in testing this would be appreciated...

    The class is based on the "old" (MODx Evolution) 0.5.3b Docmanager snippet(by ur001)
    and on the following files from the MODx Revolution core:

    • core/model/modx/processors/resource/create
    • core/model/modx/processors/resource/delete
    • core/model/modx/processors/resource/update
    and a little bit on the Revolution DocumentManager class

    Example of use (creating a new document):
       require_once('core/components/docbuilder/moddocumentbuilder.class.inc.php');
       $doc = new modDocumentBuilder();
       $doc->set('parent',$folder);
       $doc->set('alias','post'.strftime('%Y-%m-%d %H:%M:%S'));
       $doc->set('content','document content');
       $doc->set('template','GuestBookComments'); // template must be set before TV's
       $doc->set('tvComment','post to comment template variable'); // beware: template must be set before TV's
       $doc->setResourceGroup('Group',true); // add (in case of 'true') document to resource group Group
                                            //   ('false' is used to remove a document from a resource group)
                                            //   using the group-id to set the resource group is also permitted
       $doc->save();                // document will be created in MODx with indicated values
       $idDoc = $doc->get('id');    // to get the id of the document; for new documents this can only be done after save()
       $urlDoc = $doc->get('preview_url');  // to get the preview_url (WARNING: will not always deliver right result)

    More information:
    To change (update) an existing document:
       $doc = new Document($id); // $id = id of the existing document
       $doc->set('content','document content');
       $doc->save(); // document will be created with indicated values

    To delete an existing document (with all its children!):
       $doc = new Document($id); // $id = id of the existing document
       $doc->delete();

    To get the value of a field of an existing document:
       $doc = new Document($id); // $id = id of the existing document
       $pagetitle=$doc->get('pagetitle');

    To get an overview of the resource groups the resource belongs to:
       $doc = new Document($id); // $id = id of the existing document
       $groups=$doc->getResourceGroups(); // resturns array of resource group names

    To get a tv value from a document:
       $doc = new Document($id); // $id = id of the existing document
       $MyTvValue=$doc->get('tvMyTvName');//add "tv" before the name of your tv.
    
    To duplicate a document (documents are duplicated with their tv values,
    but without their children):
       $doc = new Document($Id_Of_Document_You_Want_duplicate);
       $doc->duplicate();
       $doc->save();

    To get an array of the id’s of the (direct) children of a document use the following:
       $doc = new Document($Id); // id of existing document
       $childrenArray = $doc->getChildren();


    Version attached is now 0.8 from August 10th, 2010
      • 3749
      • 24,544 Posts
      It’s an interesting project and may help people with legacy code who want to port it to Revolution.

      That said, most (maybe all) of the functions you provide are already built into the Revolution object model and using the built-in methods would be safer.

      Here’s a sightly modified example from the EZfaq install script:

                  $default_template = $modx->getOption('default_template');
      
                  $r = $modx->newObject('modResource');
      
                  $r->set('class_key','modResource');
                  $r->set('context_key','web');
                  $r->set('type','document');
                  $r->set('contentType','text/html');
                  $r->set('pagetitle','Sample FAQ Page');
                  $r->set('longtitle','Sample FAQ Page');
                  $r->set('description','Sample FAQ Page');
                  $r->set('alias','faq');
                  $r->set('published','1');
                  $r->set('parent','0');
                  $r->set('isfolder','1');
                  $r->setContent('[[EZfaq]]');
                  $r->set('richtext','0');
                  $r->set('menuindex','99');
                  $r->set('searchable','1');
                  $r->set('cacheable','1');
                  $r->set('menutitle','FAQ');
                  $r->set('donthit','0');
                  $r->set('hidemenu','0');
                  $r->set('template',$default_template);
      
                  $r->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
        • 28215
        • 4,149 Posts
        Neat, but xPDO already does most of this:

        Quote from: Black at Mar 10, 2010, 11:07 AM

        Example of use (creating a new document):
         require_once('core/components/docbuilder/moddocumentbuilder.class.inc.php');
           $doc = new modDocumentBuilder();
           $doc->set('parent',$folder);
           $doc->set('alias','post'.strftime('%Y-%m-%d %H:%M:%S'));
           $doc->setResourceGroup('Group',true); // add (in case of 'true') document to resource group Group
                                                //   ('false' is used to remove a document from a resource group)
                                                //   using the group-id to set the resource group is also permitted
           $doc->set('syncsite', true); // to make sure that the cache is cleared after the document is saved
           $doc->save();                // document will be created in MODx with indicated values
           $idDoc = $doc->get('id');    // to get the id of the document; for new documents this can only be done after save()
           $urlDoc = $doc->get('preview_url');  // to get the preview_url (WARNING: will not always deliver right result)

        in MODx/xPDO:
        $doc = $modx->newObject('modDocument');
        $doc->set('parent',$folder);
        $doc->set('alias',$alias);
        $doc->set('published',true);
        $doc->save();
        $modx->cacheManager->clearCache();
        $url = $modx->makeUrl($doc->get('id'));
        




        To change (update) an existing document:
        $doc = new Document($id); // $id = id of the existing document
           $doc->set('content','document content');
           $doc->save(); // document will be created with indicated values
        
        in MODx/xPDO:
        $doc = $modx->getObject('modResource',$id);
        $doc->setContent($content);
        $doc->save();
        




        To delete an existing document (with all its children!):
        $doc = new Document($id); // $id = id of the existing document
           $doc->delete();
        in MODx/xPDO:
        $doc = $modx->getObject('modResource');
        $doc->set('deleted',true);
        /* or permanently delete it */
        $doc->remove();
        



        To get the value of a field of an existing document:
           $doc = new Document($id); // $id = id of the existing document
           $pagetitle=$doc->get('pagetitle');
        in MODx/xPDO:
        $doc = $modx->getObject('modResource',$id);
        $pagetitle = $doc->get('pagetitle');
        



        To get an overview of the resource groups the resource belongs to:
           $doc = new Document($id); // $id = id of the existing document
           $groups=$doc->getResourceGroups(); // resturns array of resource group names
        in MODx/xPDO:
        $doc = $modx->getObject('modResource',$id);
        $resourceGroups = $modx->getMany('ResourceGroupResources');
        /* returns groups as modResourceGroupResource objects, this can also just get names via: */
        
        $c = $modx->newQuery('modResourceGroup');
        $c->innerJoin('modResourceGroupResource','ResourceGroupResources');
        $c->where(array(
        	'ResourceGroupResources.document' => $doc->get('id');
        ));
        $resourceGroups = $modx->getCollection('modResourceGroup',$c);
        
        /* and to get the names */
        $names = array();
        foreach ($resourceGroups as $resourceGroup) {
           $names[] = $resourceGroup->get('name');
        }
        



        To get a tv value from a document:
           $doc = new Document($id); // $id = id of the existing document
           $MyTvValue=$doc->get('tvMyTvName');//add "tv" before the name of your tv.
        
        in MODx/xPDO:
        $doc = $modx->getObject('modResource',$id);
        $value = $doc->getTVValue('MyTvName');
        



        To duplicate a document (documents are duplicated with their tv values,
        but without their children):
        $doc = new Document($Id_Of_Document_You_Want_duplicate);
           $doc->duplicate();
           $doc->save();
        in MODx/xPDO:
        $doc = $modx->getObject('modResource',$id);
        $newDoc = $modx->newObject('modDocument');
        $newDoc->fromArray($doc->toArray());
        $newDoc->save();
        




        To get an array of the id’s of the (direct) children of a document use the following:
           $doc = new Document($Id); // id of existing document
           $childrenArray = $doc->getChildren();
        in MODx/xPDO:
        $doc = $modx->getObject('modResource',$id);
        $doc->getMany('Children'); /* returns children as modResource objects */
        


        I think it might be a bit unnecessary to use an assistance class like you’ve created, as it would add a whole bunch of extra overhead.

        That said, we can definitely look into discussing extra helper methods for the mod* classes.

        Kudos for hacking into MODx Revo!
          shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
          • 3496
          • 101 Posts
          Shaun and Bob,
          Thanks for your responses.
          Neat, but xPDO already does most of this:
          Ok, clear.
          I must admit that I had my doubts during the development. The main reasons I continued anyhow were the following:

          • The code in the processors was rather long (code used for creating, changing, duplicating, deleting MODx resources from the manager); if all that code is not necessary, why is it there?
          • I have some existing code using the Evolution DocumentManager class; just getting a new version of that class was useful for me.
          • Handling templates, template variables, resource groups and users seemed not so easy with the basic xPDO functions (I didn’t know of the $doc->getTVValue() method).
          Set basic parameters of document
          in modDocumentBuilder:
          $doc = new modDocumentBuilder();
          $doc->set(’parent’,$folder);
          $doc->set(’alias’,’post’.strftime(’%Y-%m-%d %H:%M:%S’));
          in MODx/xPDO:
          $doc = $modx->newObject(’modDocument’);
          $doc->set(’parent’,$folder);
          $doc->set(’alias’,$alias);
          If only these kinds of statements are needed, the direct xPDO functions should indeed be used (although there were some extra checks in the processors that I also included in this class...).
          $doc->set(’syncsite’, true);
          Sorry, this should have been removed from my example; to clear the cache is the default behavior in the class.
          Get URL
          modDocumentBuilder:
          $urlDoc = $doc->get(’preview_url’);
          xPDO:
          $url = $modx->makeUrl($doc->get(’id’));
          Euh, I think that (the current implementation of) makeUrl will not deliver the url if used in this way (right after creating the resource). See the following forum discussion: http://modxcms.com/forums/index.php/topic,46524.0.html.
          Delete document:
          $doc->set(’deleted’,true);
          According to my testing this xPDO statement does not fill in "deletedby" and does not delete the children of the document.
          Get simple document parameters
          modDocumentBuilder:
          $doc = new Document($id); // $id = id of the existing document
          $pagetitle=$doc->get(’pagetitle’);
          MODx/xPDO:
          $doc = $modx->getObject(’modResource’,$id);
          $pagetitle = $doc->get(’pagetitle’);
          I agree, for these simple kind of statements, the xPDO functions should be used.
          Get resourcegroups
          modDocumentBuilder:
          $doc = new Document($id); // $id = id of the existing document
          $groups=$doc->getResourceGroups(); // resturns array of resource group names
          MODx/xPDO:
          $doc = $modx->getObject(’modResource’,$id);
          $resourceGroups = $modx->getMany(’ResourceGroupResources’);
          /* returns groups as modResourceGroupResource objects, this can also just get names via: */

          $c = $modx->newQuery(’modResourceGroup’);
          $c->innerJoin(’modResourceGroupResource’,’ResourceGroupResources’);
          $c->where(array(
          ’ResourceGroupResources.document’ => $doc->get(’id’);
          ));
          $resourceGroups = $modx->getCollection(’modResourceGroup’,$c);

          /* and to get the names */
          $names = array();
          foreach ($resourceGroups as $resourceGroup) {
          $names[] = $resourceGroup->get(’name’);
          }
          Here the xPDO code is more complicated; perhaps an extra function could be useful.
          Probably the same goes for setting a resource group for a document.
          Get template variable
          in xPDO:
          $doc = $modx->getObject(’modResource’,$id);
          $value = $doc->getTVValue(’MyTvName’);
          I must admit that I didn’t know this function yet.
          Quote
          To duplicate a document
          modDocumemtBuilder:
          $doc = new Document($Id_Of_Document_You_Want_duplicate);
          $doc->duplicate();
          $doc->save();
          MODx/xPDO:
          $doc = $modx->getObject(’modResource’,$id);
          $newDoc = $modx->newObject(’modDocument’);
          $newDoc->fromArray($doc->toArray());
          $newDoc->save();
          The two versions of the example code will not accomplish the same.
          With these xPDO statements settings like "createdby" and "editedby" will be copied from the original document, while I think they should be changed to the currently logged in user.
          And will template variables and resource groups be duplicated in this way?
          I think it might be a bit unnecessary to use an assistance class like you’ve created, as it would add a whole bunch of extra overhead.
          That said, we can definitely look into discussing extra helper methods for the mod* classes.
          That would be great!
          Kudos for hacking into MODx Revo!
          Thanks!
          (it was worth it; if only for everything I learned)
            • 3515
            • 19 Posts
            Hi, everyone! This code:

            	define('MODX_CORE_PATH', 'core/');
            	define('MODX_CONFIG_KEY', 'config');
            	require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
            	require_once('core/components/docbuilder/moddocumentbuilder.class.inc.php');
            	$modx= new modX();
            	$modx->initialize('mgr');
            	$modx->db->query('alter table modx_site_content auto_increment=0');
            
            	
            	//Удаление старого каталога
            	$doc=new modDocumentBuilder('5');
            	$doc->delete();
            


            returns Fatal error: Call to undefined function getchildren() in <server>\www\core\components\docbuilder\moddocumentbuilder.class.inc.php on line 406... Any ideas?
              • 3749
              • 24,544 Posts
              Quote from: Vincent at Jul 26, 2010, 01:49 AM

              Hi, everyone! This code:

              	define('MODX_CORE_PATH', 'core/');
              	define('MODX_CONFIG_KEY', 'config');
              	require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
              	require_once('core/components/docbuilder/moddocumentbuilder.class.inc.php');
              	$modx= new modX();
              	$modx->initialize('mgr');
              	$modx->db->query('alter table modx_site_content auto_increment=0');
              
              	
              	//Удаление старого каталога
              	$doc=new modDocumentBuilder('5');
              	$doc->delete();
              


              returns Fatal error: Call to undefined function getchildren() in <server>\www\core\components\docbuilder\moddocumentbuilder.class.inc.php on line 406... Any ideas?

              I’m not sure what that line is intended to do. If it gets an array of IDs of the children, it should be something like:

              $modx->getChildIds($id);


              Where $id is the ID of the resource you want the children of. It will return an empty array on failure.

              If it’s intended to get the child objects themselves, you want

              $resource->getMany('Children');


              Where $resource is a reference to the resource you want the children of. Also returns an empty array on failure.

              Hope this helps.
                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
                • 3515
                • 19 Posts
                Seems like this function returns get array of children document to be deleted with it... So, I have to correct modDocumentBuilder.php, - I’ll try! Thanks for your help!)) (You already twice saved me... - the BIG thanks!!! smiley )
                  • 3496
                  • 101 Posts
                  Oops, obviously I didn’t even test that part of the code...

                  The getChildren line should be replaced with the following:
                  if ($loop) $this->_getChildren($child, $ar_children, $loop, $delcheck);
                  

                  See the updated attachment in the original post for a new version of the modDocumentBuilder code (including some other small corrections).

                  As earlier, the code starts with the relevant "user-manual".
                    • 3496
                    • 101 Posts
                    New version attached to the original post (version 0.8, date: August 10th)