Convert raw form HTML to post for cURL

I’m attempting to build a script to automate a common process that needs to done over and over again. The idea is to use cURL to authenticate than procede to a specific admin page. That admin page than has a form. The fields for that are known so they can be hard coded and sent via using cURL postfields option. However, once that form is submitted another form is than shown. Unlike the previous form the fields for this next form are dynamic and can change based on different circumstances. What I would like to do is collect all the form data on this form than post it back to the page using cURL. However, my problem lies in that I need to either find or build a library which can accept a HTML string as input and parse out all the post fields so that the postfields option for cURL can be used to post back the form with the data.

Here is the code up to now which is very rough and more of a proof of concept at this point.


<?php

define('PAGE_MANAGER_IMPORT','admin/structure/pages/import');

/**
 * Login URL
 */
$domain = 'http://local.spark';
$user = 'admin';
$pwd = 'mypass';
$cookiefile = 'ctools_import_cookies';

/**
 * Initiate cURL
 */
$ch = curl_init();

/**
 * Set cURL options
 */
curl_setopt($ch,CURLOPT_URL,"$domain/user");
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,0);

/**
 * Execute
 */
$content = curl_exec($ch);
curl_close($ch);
unset($ch);
 
//echo $content; exit;

// -----------------------------------------------------------------------------------------
 
/** 
 * Extract form build ID
 */
$matches = array();
preg_match_all('<input\\s?type="hidden"\\s?name="form_build_id"\\s?value="(.*?)"\\s\\/>',$content,$matches);
 
//echo '<pre>'.print_r($matches,true).'</pre>';

/**
 * Assign build ID
 */
 $form_build_id = $matches[1][0];
 
//echo "<p>build id: $form_build_id</p>";

/**
 * Build post
 */
 $post = array(
 	'form_build_id'=> $form_build_id,
 	'form_id'=> 'user_login',
 	'op'=> 'Log in',
 	'name'=> $user,
 	'pass'=> $pwd
 );
 
 // ----------------------------------------------------------------------------------
 
/**
 * Login
 */
$ch = curl_init();
 
/**
* Set cURL options
*/

$post_data = array();
foreach($post as $key=>$value) {
	$post_data[] = "$key=$value";
}
 
curl_setopt($ch,CURLOPT_URL,"$domain/user");
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,0);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,implode('&',$post_data));
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookiefile);
 
curl_exec($ch);
curl_close($ch);
unset($post_data);

//echo $content;

// ---------------------------------------------------------------------------------------
 
/**
 * goto admin page
 */
$ch = curl_init();
 
/**
* Set cURL options
*/
 
curl_setopt($ch,CURLOPT_URL,"$domain/".PAGE_MANAGER_IMPORT);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch,CURLOPT_COOKIEFILE,$cookiefile);

$content = curl_exec($ch);
curl_close($ch);

/**
 * Need to convert $content to post array for another curl call.
 */
 
echo $content;

// --------------------------------------------------------------------------------------


 ?>

As you should see at the bottom the very last call to curl_exec returns content. This is a content for the form which I need to than convert to a post string which can be sent in another post using the postfields option. Essentially, I need a php library that does a similar thing as jQuery when it comes to collecting data for AJAX requests but with PHP. Is anyone aware of such a library?

If anyone is familiar with Drupal what I’m trying to build is a way to push/sync a ctools object across several sites at once. I know that features is an option but that requires updating each site individually. I would just like to be able to have a single ctools object imported across several sites without the need to visit each and every site. So that is what I’m attempting to build here. The goal here is to be define a list of say 13 sites than in a single run push a ctools object to all of them like a panel page for instance. Rather than needing to visit each and every site and push the panel manually or with features.

So… slice out the contents of the form (<form>…</form>), and parse anything inside a form tag (<input* />, <textarea *</textarea>, <select *</select>)?

That is correct.

If a library doesn’t exist I was going use query path and write the rest myself. Query path seems like it would handle the bulk of the work selecting the form tags.

Seeing if a better solution is out there though…

Query path is working like a charm.