We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 21872
    • 95 Posts
    Another potentially dumb question, but any help would be greatly appreciated. I have a large collection of static HTML files I need to turn into resources. I’ve written a script that does the following:
    1.) opens the next file in a directory
    2.) runs the file through Tidy
    3.) creates a DOMDocument and loads the tidied xhtml into it
    4.) create DomXpath object, perform a bunch of queries and insert the results into an that contains fields corresponding to pagetitle, longtitle, and content
    5.) loops through the nodes in each nodelist and appends them to a new domdocument which is then converted to a string and assigned to the original key .... e.g. $item[’content’] starts out as a nodelist and ends as a string
    6.) performs some final cleanup with very gnarly regex on the introtext, content, and FRUL values
    7.) adds keys and values for all other fields in modx_site_content (not entirely trivial, this content is organized by date and the date has to be derived from a subset of the file name and a value extracted from the contents of the file, both to get a time for the publishedon field and to work out what the parent id should be)
    8.) ....
    9.) repeat until out of files

    8 is supposed to be "create new resource and insert values" but I don’t know how to do this. At least, not how to do it the right right way.

    At the end of each pass, I have an array containing a value for every field in modx_site_content, the next step, in my mind, is to insert each resource into the database, grab the new ID with mysql_insert_id(), and update a custom table that will store original URL, new FRUL, and corresponding resource ID.

    I’m afraid I really don’t fully grok how to work with xPDO and haven’t found an example of how to create resources (other than clicking the appropriate icon in the manager smiley) that is sufficiently clear and simple for my very basic understanding of 1) PHP, 2) MySQL, 3) MODx.

    Could someone please explain and/or provide an example of the right way to get this stuff into the database?

    Thanks in advance.
      • 4172
      • 5,888 Posts
      here’s an example how you can create a resource from array and also create TVs:
      you can also use a TV for your old url and let modx generate an alias for your new furl (modx will generate the new furl automatically with modx-makeUrl() from alias when you need that later)

      <?php
      
      
      $fields=array();
      $fields['content']='my content';
      $fields['pagetitle']='my pagetitle';
      $fields['myTV']='tvcontent';
      
      $doc = $modx->newObject('modResource');
      $doc->set('createdby', $modx->user->get('id'));
      
      //set docfields from fields-array
      foreach ($fields as $field=>$value){
          $doc->set($field, $value);
      }
      
      $doc->set('template', '1');//set your template
      $doc->save();
      
      //set TVs from fields-array
      foreach ($fields as $field=>$value)
      {
          if ($tv = $modx->getObject('modTemplateVar', array ('name'=>$field)))
          {
              /* handles checkboxes & multiple selects elements */
              if (is_array($value)) {
                  $featureInsert = array();
                  while (list($featureValue, $featureItem) = each($value)) {
                       $featureInsert[count($featureInsert)] = $featureItem;
                  }
                  $value = implode('||',$featureInsert);
              }	
              $tv->setValue($doc->get('id'), $value);
              $tv->save();
          }
      }
      
      ?>
        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 3749
        • 24,544 Posts
        You can set any of the resource fields in your code. There’s a list of them here (near the bottom of the page): http://bobsguides.com/revolution-objects.html. You might want to set the created on field like this:

        $fields['createdon'] = time();


        If you have the $fields filled already in your code, you can just do this instead of the first foreach() call in Bruno17’s post to set the fields of the resource:

        $resource = $modx->newObject('modResource',$fields);


        It’s good form to set the content field with

        $modx->setContent('Some Content');
        //or 
        $modx->setContent($contentVariableName);


        after the newObject call but before the save().

        See this for information on how to create your custom DB table so you can use xPDO with it:

        http://bobsguides.com/custom-db-tables.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
          • 28215
          • 4,149 Posts
          In 2.0.5 you can just do:

          $response = $modx->runProcessor('resource/create',array(
             'pagetitle' => 'Fun Page',
             'published' => true,
             'content' => 'stuff here',
             /* etc */
          ));
          if ($response->isError()) {
             if ($response->hasFieldErrors()) {
                 $fieldErrors = $response->getAllErrors();
                 $errorMessage = implode("\n",$fieldErrors);
             } else {
                 $errorMessage = 'An error occurred: '.$response->getMessage();
             }
             return $errorMessage;
          }
          return 'Success!';
          


            shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
            • 3749
            • 24,544 Posts
            Shaun, am I correct that calling the processor is preferred over newObject(), because it checks permissions and handles default settings and sanity checks for the fields?
            (argghh! -- more rewriting -- it’s never going to end is it?).

            OTOH, newObject() should be a lot faster and more efficient in a utility snippet if you have all the necessary fields set correctly.


            I assume that the following would also work if you have the $fields set when importing resources as the OP intends:

            $response = $modx->runProcessor('resource/create',$fields);
              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
              Quote from: BobRay at Dec 08, 2010, 03:28 PM

              Shaun, am I correct that calling the processor is preferred over newObject(), because it checks permissions and handles default settings and sanity checks for the fields?
              (argghh! -- more rewriting -- it’s never going to end is it?).
              OTOH, newObject() should be a lot faster and more efficient in a utility snippet if you have all the necessary fields set correctly.

              Yes, processor calls are generally more preferred if the user has the correct permissions. It does all the sanity checks, permission checks, etc.

              Also, processor calls can handle more than just creating the Resource - they can set TV values and such for the Resource. We’ll definitely have more documentation for each processor coming - just had to get 2.0.5 out first.


              I assume that the following would also work if you have the $fields set when importing resources as the OP intends:
              $response = $modx->runProcessor('resource/create',$fields);

              Yes, although you should check the top of the processor’s file to see what parameters it needs. Example, resource/create:

              
               * @param string $pagetitle The page title.
               * @param string $content The HTML content. Used in conjunction with $ta.
               * @param integer $template (optional) The modTemplate to use with this
               * resource. Defaults to 0, or a blank template.
               * @param integer $parent (optional) The parent resource ID. Defaults to 0.
               * @param string $class_key (optional) The class key. Defaults to modDocument.
               * @param integer $menuindex (optional) The menu order. Defaults to 0.
               * @param string $variablesmodified (optional) A collection of modified TVs.
               * Along with $tv1, $tv2, etc.
               * @param string $context_key (optional) The context in which this resource is
               * located. Defaults to web.
               * @param string $alias (optional) The alias for FURLs that this resource is
               * designated to.
               * @param integer $content_type (optional) The content type. Defaults to
               * text/html.
               * @param boolean $published (optional) The published status.
               * @param string $pub_date (optional) The date on which this resource should
               * become published.
               * @param string $unpub_date (optional) The date on which this resource should
               * become unpublished.
               * @param string $publishedon (optional) The date this resource was published.
               * Defaults to time()
               * @param integer $publishedby (optional) The modUser who published this
               * resource. Defaults to the current user.
               * @param json $resource_groups (optional) A JSON array of resource groups to
               * assign this resource to.
               * @param boolean $hidemenu (optional) If true, The resource will not show up in
               * menu builders.
               * @param boolean $isfolder (optional) Whether or not the resource is a
               * container of resources.
               * @param boolean $richtext (optional) If true, MODx will render the available
               * RTE for editing this resource.
               * @param boolean $donthit (optional) (deprecated) If true, MODx will not log
               * visits on this resource.
               * @param boolean $cacheable (optional) If false, the resource will not be
               * cached.
               * @param boolean $searchable (optional) If false, the resource will not appear
               * in searches.
               * @param boolean $syncsite (optional) If false, will not empty the cache on
               * save.
              
                shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
                • 3749
                • 24,544 Posts
                I see the processor also implements addLock(), which could be critical on a busy site.

                BTW, shouldn’t $template default to the system default template rather then 0?
                  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
                  It does, the docs are wrong. tongue
                    shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
                    • 3749
                    • 24,544 Posts
                    Quote from: splittingred at Dec 08, 2010, 03:58 PM

                    It does, the docs are wrong. tongue

                    I was looking at out-of-date code. I see that it does use the default template now.
                      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
                      • 21872
                      • 95 Posts
                      This has been extremely helpful, thank you all!

                      I only encountered one problem I haven’t been able to solve based off the information you’ve provided here, and that is why the alias I provided doesn’t work unless I manually save the newly created resource.

                      All I did was build an array corresponding to the vaules for a resource and:
                      $resource = $modx->newObject(’modResource’,$site_content);
                      $resource->save();

                      But, while the values for $site_content[’alias’]; end up in the database and are visible in the resource editor, unless I modify the resource and save it manually, it won’t load at that address. What did I neglect to do?

                      Thanks again.