My client needs a biblio node created automatically when another piece of content is created.

calling drupal_execute on a biblio_node_form is getting to the validation hook without errors but it is not getting past that. if leave necessary bits of the form out, i do get form validation errors.

In the process of debugging, I saw that nodeapi is being invoked with $node->type == 'biblio' && $op == 'validate' when I select 'web article' manually creating a biblio node.

It was called with $form_state['values]['op'] = ''Populate using DOI''

I thought maybe that had something to do with what I was trying to do, but I couldn't get around it.


function auto_biblio_entry_menu(){
		$items['admin/settings/biblio/auto'] = array(
		  'title'             => 'Auto Create Biblio Settings',
		  'page callback'     => 'drupal_get_form',
		  'page arguments'    => array('auto_biblio_entry_settings'),
		  'access arguments'  => array('administer biblio'),
		  'type'              => MENU_NORMAL_ITEM,
		);
		return $items;
}

function auto_biblio_entry_settings(){
	$options = node_get_types('names');
	
	$form['auto_biblio_entry_types'] = array(
		'#type' => 'checkboxes',
		'#title' => t('These node types automatically have biblio entries created'),
		'#options' => $options,
		'#default_value' => variable_get('auto_biblio_entry_types', array()),
		'#description' => t('A biblio node will automatically be created with type "Web Article"'),
	);
	return system_settings_form($form);
}

function auto_biblio_entry_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){

	if($node->type == 'biblio' && $op == 'validate'){
	//	print "validating biblio:<br /><pre>"; print_r($node); print "</pre>";
	}
	if( $op == 'insert' &&  in_array($node->type, variable_get('auto_biblio_entry_types', array() ) ) ){

		global $base_url;
		$bib_node = array(
			'uid' => (string) $node->uid,
			'name' => (string) $user->name, 
      'type' => 'biblio', 
      'language' => '', 
      'body' => NULL, 
      'title' => $node->title, 
      'format' => NULL, 
      'status' => true, 
      'promote' => false, 
      'sticky' => false, 
      'created' => time(), 
      'revision' => false, 
      'comment' => '0', 
      );
     $bib_node = (object) $bib_node;
	//	$bib_node->uid = $node->uid;
	  module_load_include('inc', 'node', 'node.pages');
	  
	  
		$values = array();
	//	$values['op'] = t('Populate using DOI');
		$values['biblio_type'] = "107";
		$values['title'] = $node->title;
		$form_state = array();
		
		$values['biblio_year'] = date('Y', $node->created);
		$form_state['values'] = $values;
	
	//	drupal_execute('biblio_node_form', $form_state, $bib_node);
		$x = 0;
		foreach($node->field_author_reference as $author){
		dpm($x . " time through");
			$values['biblio_contributors'] = array(
				'1' => array(
					"$x" => array(
						'name' => _auto_biblio_entry_author_name($author['uid']),
						'auth_type' => 1,
						'cid' => null,
						'rank' => $x,
						),
					),
				);
				$x = $x + 1;
		}
		$values['biblio_publisher'] = "Solutions";
	  $values['biblio_type'] = "107";
		$values['biblio_abst_e'] = $node->field_abstract[0]['value'];
		$values['biblio_url'] = $base_url . '/node/' . $node->nid;
		$values['biblio_type_name'] = t('Web Article');
		$values['name'] = $node->name;
		

	/*	$values['doi_data'];
		$values['paste_data']; */
		$values['op'] = t('Save');
		
		$form_state = array();
		$form_state['values'] = $values;
		drupal_set_message("creating bib after feat");
		dpm($form_state);
		drupal_execute('biblio_node_form', $form_state, $bib_node);
		$errors = form_get_errors();
		dpm($errors);
		if (count($errors)){
			drupal_set_message("A biblio node may not have been created");
		}
	}
}

function _auto_biblio_entry_author_name($uid){
	$result = db_query('SELECT value from {profile_values} WHERE uid = %d AND fid IN(1,2)', $uid);
	$first = db_result($result);
	$last = db_result($result);
	//Return LastName, [F]irst letter of First Name
	return $last . ', ' . $first[0];
}

The code is sort of ugly in the middle since I was trying to debug it.

Comments

rjerome’s picture

I can't say that I've ever tried to populate a biblio node using drupal_execute(), so I can't say off the top of my head what might be wrong. As you are no doubt aware, this is "more or less" a multi step form, where the first step is to either supply DOI, BibTex or select a publication type (Book, Journal, etc.), the input form is then rebuilt based on this first step. Also, you should be aware that biblio_form_alter() is used to hide most of the form widgets the first time through. This is all a bit of a hack that could probably be done in a cleaner fashion (and likely will be in 7.x as the form is not working at all there).

This is rather timely though since I'm right in the middle of writing unit tests for the 7.x version and I'm sure I'll need to solve this issue, so I guess I now know what my next test will be :-)

I'll give it a try and see what I can come up with.

Ron.

gdoteof’s picture

I got this working.

What ended up happening is I had I to make it think it was at the second part of the form by supplying the ['storage'] for Web Article.


function auto_biblio_entry_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){

	if( $op == 'insert' && $node->type=="feature_article" ){
    //prepare the Bib node for insertion
		global $base_url;
		$bib_node = array(
			'uid' => (string) $node->uid,
			'name' => (string) $user->name, 
      'type' => 'biblio', 
      'language' => '', 
      'body' => NULL, 
      'title' => $node->title, 
      'format' => NULL, 
      'status' => true, 
      'promote' => false, 
      'sticky' => false, 
      'created' => time(), 
      'revision' => false, 
      'comment' => '0', 
      );
    $bib_node = (object) $bib_node;
    //load the necessary include files to submit the form
	  module_load_include('inc', 'node', 'node.pages');

		$values = array();
		
    //populate the contributor field from the author reference	
		$x = 0;
		if($node->field_author_reference){
			foreach($node->field_author_reference as $author){
				$values['biblio_contributors'][1][$x] = array(
							'name' => _auto_biblio_entry_author_name($author['uid']),
							'auth_type' => 1,
							'cid' => null,
							'rank' => $x,
					);
					$x = $x + 1;
			}
		}
    //Set up some biblio fields
		$values['biblio_publisher'] = "Solutions";
	  $values['biblio_type'] = "107";
		$values['biblio_abst_e'] = $node->field_abstract[0]['value'];
		$values['biblio_url'] = $base_url . '/node/' . $node->nid;
		$values['biblio_type_name'] = t('Web Article');
		$values['biblio_year'] = date('Y', $node->created);
		$values['name'] = $node->name;
		
    //We wwant to insert into the database
		$values['op'] = t('Save');
	

    //build the form	
		$form_state = array();
		$form_state['values'] = $values;
		//(it's a web article)
		$form_state['storage']['biblio_type'] = "107";
    
		//Submit the form
		drupal_execute('biblio_node_form', $form_state, $bib_node);


		//Find the NID for the node we just created
    $result = db_query('SELECT nid FROM {node} WHERE title = "%s" ORDER BY created DESC LIMIT 1', check_plain($node->title));
		$bib_nid = db_result($result);

		//Set the biblio we just created as the citation for the feature article being inserted
		$node->field_citation[0]['nid'] = $bib_nid;
		$errors = form_get_errors();
		if (count($errors)){
			drupal_set_message("A biblio node may not have been created");
		}
	}
}

function _auto_biblio_entry_author_name($uid){
	$result = db_query('SELECT value from {profile_values} WHERE uid = %d AND fid IN(1,2)', $uid);
	$first = db_result($result);
	$last = db_result($result);
	//Return LastName, [F]irst letter of First Name
	return $last . ', ' . $first[0];
}

rjerome’s picture

It hadn't occurred to me before to ask, but why bother building a form and submitting it with drupal_execute? Why not just build a node object and save it using node_save() like this...

function auto_biblio_entry_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){

    if( $op == 'insert' && $node->type=="feature_article" ){
    //prepare the Bib node for insertion
        global $base_url;
        $bib_node = array(
            'uid' => (string) $node->uid,
            'name' => (string) $user->name,
      'type' => 'biblio',
      'language' => '',
      'body' => NULL,
      'title' => $node->title,
      'format' => NULL,
      'status' => true,
      'promote' => false,
      'sticky' => false,
      'created' => time(),
      'revision' => false,
      'comment' => '0',
      );
    //load the necessary include files to submit the form
      module_load_include('inc', 'node', 'node.pages');

        $values = array();
       
    //populate the contributor field from the author reference   
        $x = 0;
        if($node->field_author_reference){
            foreach($node->field_author_reference as $author){
                $values['biblio_contributors'][1][$x] = array(
                            'name' => _auto_biblio_entry_author_name($author['uid']),
                            'auth_type' => 1,
                            'cid' => null,
                            'rank' => $x,
                    );
                    $x = $x + 1;
            }
        }
    //Set up some biblio fields
        $values['biblio_publisher'] = "Solutions";
        $values['biblio_type'] = "107";
        $values['biblio_abst_e'] = $node->field_abstract[0]['value'];
        $values['biblio_url'] = $base_url . '/node/' . $node->nid;
        $values['biblio_type_name'] = t('Web Article');
        $values['biblio_year'] = date('Y', $node->created);
        $values['name'] = $node->name;
       
       $bib_node =(object)  array_merge($bib_node, $values);
       
       node_save($bib_node);

       //Set the biblio we just created as the citation for the feature article being inserted
     
        if (!isset($bib_node->nid)){
            drupal_set_message("A biblio node may not have been created");
        }
        else {
            $node->field_citation[0]['nid'] = $bib_node->nid; // nid is filled in by node_save
       }
    }
}

function _auto_biblio_entry_author_name($uid){
    $result = db_query('SELECT value from {profile_values} WHERE uid = %d AND fid IN(1,2)', $uid);
    $first = db_result($result);
    $last = db_result($result);
    //Return LastName, [F]irst letter of First Name
    return $last . ', ' . $first[0];
}
gdoteof’s picture

Status: Active » Fixed

I started on that route but wasn't able to get the bib objects filled in correctly and ended up digging more in the drupal_execute way.

Though I am not sure if I was doing something wrong or what, I didn't save any of that code.

rjerome’s picture

Should work, cause that's exactly what's being done with the import of data from files.

Ron.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.