Example: node.save and CCK fields in PHP client code

Last updated on
30 April 2025

You are browsing documentation for an older version of Drupal, which is not supported any longer, and the information may not be correct. See current documentation for Contributed modules

Services 6.x-2.x-dev on Drupal 6.14. Uses the XML-RPC for PHP library at http://phpxmlrpc.sourceforge.net/. Thanks to clues from http://drupal.org/node/303285 and the services tester, it includes some code for populating CCK fields ("field_publication", "field_byline", etc.). This is pre-production code for importing articles to a newspaper website, designed to run on the command line. I just left the parseXML() function as an example.

<?php
  require('./xmlrpc-3.0.0.beta/lib/xmlrpc.inc');
  $username = "username";
  $pass = "password";
  $domain = "example.com";
  $publication = "The Daily Drupal";
  $servicehost = "example.com";
  $servicepath = "services/xmlrpc";
  $sessid = "";
  $uid = 0;
  $xmlpath = "/path/to/xml";
  $processdir = "/path/to/processed";
  $successdir = "$processdir/success";
  $failuredir = "$processdir/failure";
  
  // Make initial connection to get a session ID
  $m = new xmlrpcmsg('system.connect', array());
  $c = new xmlrpc_client($servicepath, $servicehost, 80);
  $c->return_type = "phpvals";
  
  $r = &$c->send($m);
  if(!$r->faultCode()){
    $v = $r->value();
    $sessid = ($v['sessid']);
  }else{
    die("An error occurred on system.connect: ".$r->faultString()."\n");
  }

  // Using the session ID from the first connection, log in to the server
  $m = new xmlrpcmsg("user.login",
    array(
      new xmlrpcval($sessid),
      new xmlrpcval($username),
      new xmlrpcval($pass))
  );
	// If login is successful, user object and a new sessid will be returned
  $r = &$c->send($m);
  if(!$r->faultCode()){
    $v = $r->value();
    // Only need uid for our purposes
    $uid = $v['user']['uid'];
    $sessid = $v['sessid'];
  }else{
    die("An error occurred on user.login: ".$r->faultString()."\n");
  }
  
  // Open the XML directory and iterate files
  $dir_handle = @opendir($xmlpath) or die("Unable to open $xmlpath\n");
  
  while ($file = readdir($dir_handle)) 
  {
    // Only get files named *.xml
    if(end(explode(".", $file)) != "xml")
      continue;
    
    // Ignore parsing errors for now and continue
    libxml_use_internal_errors(true);
    $xmldoc = simplexml_load_file("$xmlpath/$file");
    if(!$xmldoc){
      rename("$xmlpath/$file", "$failuredir/$file");
      continue;
    }
    
    // Pass the XML to be parsed and get back a PHP node structure
    $node = parseXML(&$xmldoc);
    // Call the service to create the node
    $nid = createNode($sessid, &$node);
    
    // Move file to success or failure directory
    if($nid > 0){
      rename("$xmlpath/$file", "$successdir/$file");
      print "Node $nid created.\n";
    }
    else{
      rename("$xmlpath/$file", "$failuredir/$file");
    }
  }
  
  closedir($dir_handle);
  
  function parseXML($xmldoc){
    global $publication;
    // Initialize array container for node data
    $node = array();
    
    $node["publication"] = $publication;
    $node["type"] = "story";
    $node["format"] = 2;
    
    $tmp = $xmldoc->xpath("//meta[@name='feed.doc.name']");
    $node["filename"] = trim($tmp[0]['content']);
    
    $tmp = $xmldoc->xpath("//meta[@name='feed.doc.id']");
    $node["docid"] = trim($tmp[0]['content']);
    
    $tmp = $xmldoc->xpath("//meta[@name='cms.section']");
    $node["section"] = trim($tmp[0]['content']);

    $tmp = $xmldoc->xpath("//meta[@name='cms.category']");
    $node["category"] = trim($tmp[0]['content']);

    $tmp = $xmldoc->xpath("//meta[@name='cms.release']");
    $node["releasedate"] = trim($tmp[0]['content']);

    $tmp = $xmldoc->xpath("//meta[@name='cms.expire']");
    $node["expiredate"] = trim($tmp[0]['content']);

    $tmp = $xmldoc->xpath("//meta[@name='position.rank']");
    $node["positionrank"] = trim($tmp[0]['value']);
    
    $tmp = $xmldoc->xpath("//pubdata");
    $node["positionsection"] = trim($tmp[0]['position.section']);
    $node["positionsequence"] = trim($tmp[0]['position.sequence']);
    $node["pubdataname"] = trim($tmp[0]['name']);
    
    $node["headline"] = $xmldoc->body->{'body.head'}->hedline->hl1;
    
    $node["subhead"] = $xmldoc->body->{'body.head'}->hedline->hl2;
    
    $node["byline"] = $xmldoc->body->{'body.head'}->byline->person;
    
    $node["bylinecredit"] = $xmldoc->body->{'body.head'}->bylinecredit->site;
    
    // Try to access the body in different ways to account for screwy XML
    $tmp = $xmldoc->body->{'body.content'};
    foreach($tmp->children() as $element){
      if($element->getName() !== "media")
        $node["body"] .= $element->asXML();
    }
    
    if($node["body"] === "")
      $node["body"] = $xmldoc->body->{'body.content'};
    
    // Ampersands are encoded but need to be unencoded for other HTML characters
    $node["body"] = preg_replace("/&amp;/", "&", $node["body"]);
    
    return $node;
  }
  
  // Handle node.save and CCK fields
  function createNode($sessid, $node){
    global $c, $uid, $username;
    
    $edit = new xmlrpcval(
      array(
        "uid" => new xmlrpcval($uid, "int"),
        "name" => new xmlrpcval($username),
        "type" => new xmlrpcval($node["type"]),
        "format" => new xmlrpcval($node["format"], "int"),
        "title" => new xmlrpcval($node["headline"]),
        "body" => new xmlrpcval($node["body"]),
        "field_publication" => new xmlrpcval(array(new xmlrpcval(array("value" => new xmlrpcval($node["publication"])), "struct")), "array"),
        "field_byline" => new xmlrpcval(array(new xmlrpcval(array("value" => new xmlrpcval($node["byline"])), "struct")), "array"),
        "field_section" => new xmlrpcval(array(new xmlrpcval(array("value" => new xmlrpcval($node["section"])), "struct")), "array"),
        "field_category" => new xmlrpcval(array(new xmlrpcval(array("value" => new xmlrpcval($node["category"])), "struct")), "array")
      ),
      "struct"
    );
    
    $m = new xmlrpcmsg("node.save",
      array(
        new xmlrpcval($sessid),
        $edit
      )
    );
    
    $r = &$c->send($m);
    if(!$r->faultCode()){
      $nid = $r->value();
      return $nid;
    }else{
      print ("An error occurred on node.save: ".$r->faultString()."\n");
      $nid = 0;
      return $nid;
    }
  }
?>

Help improve this page

Page status: Not set

You can: