Tutorial: Using php and curl to automate drupal tasks such as node adding or user adding
First of all you'll need the libcurl extension to php installed. The code snippets I'll present here might work if you'll convert them to Snoopy, but libcurl is faster.
What we'll do: we are going to login into Drupal and we are going to perform different operations.
1. Logging in
The first step is to log in. We're going to send the credentials using POST to the /user/login page of our Drupal website. The trick here is to capture the cookie sent by the server to use it later.
Let's init curl and set some options: the site we're going to use along with the login page and a file on our server which will store the cookie. Be careful, the user that the webserver runs as needs to have write access there. CURLOPT_POST tells curl we're going to use POST to send form data.
$crl = curl_init();
$url = "http://www.example.com/user/login";
curl_setopt($crl, CURLOPT_URL, $url);
curl_setopt($crl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");
curl_setopt($crl, CURLOPT_COOKIEJAR, "/tmp/cookie.txt");
curl_setopt($crl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($crl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($crl, CURLOPT_POST, 1);Next, we need to set the username and the password of the user we're going to login and send the data to the login script. To do this, we need to inspect the standard drupal login form and see the fields names: they're edit[name], edit[pass], edit[form_id] and op.
Warning: Be careful to init all elements of the form because missing some will make the script unusable. Particularly, edit[form_id] is essential.
// this array will hold the field names and values
$postdata=array(
"edit[name]"=>"admin",
"edit[pass]"=>"password",
"edit[form_id]"=>"user_login",
"op"=>"Log in"
);
// tell curl we're going to send $postdata as the POST data
curl_setopt ($crl, CURLOPT_POSTFIELDS, $postdata);Now it's time to log in.
$result=curl_exec($crl);
$headers = curl_getinfo($crl);
if ($headers['url'] == $url) {
die("Cannot login.");
}What we're doing here is sending the form data to the Drupal login page. We then get the headers of the response and check if the returned url is the login one. If it is, then it means we couldn't log in. This happens because, after a succesful login, Drupal redirects to http://www.example.com/user/2, 2 being the id of the logged in user. In case of failing, it returns to the login page displaying an error.
If everything went ok, we're logged in. Now you can do more serious stuff. :) Let's continue with some examples:
2. Example: Adding an image
$file = "test.jpg";
$url = "http://www.example.com/node/add/image";
curl_setopt($crl, CURLOPT_URL, $url);
$postdata = array("edit[title]"=>$file,
"edit[image]"=>"@$file.jpg",
"edit[body]"=>"This is an image posted with cURL.",
"op"=>"Submit",
"edit[format]"=>"1",
"edit[comment]"=>"2",
"edit[name]"=>"admin",
"edit[date]"=>"",
"edit[status]"=>"1",
"edit[moderate]"=>"0",
"edit[promote]"=>"1",
"edit[sticky]"=>"0",
"edit[revision]"=>"0",
"edit[images][_original]"=>"",
"edit[images][thumbnail]"=>"",
"edit[images][preview]"=>"",
"edit[form_id]"=>"image_node_form"
);
curl_setopt ($crl, CURLOPT_POSTFIELDS, $postdata);
$result=curl_exec($crl);
$headers = curl_getinfo($crl);
if ($headers['url'] == $url) {
die("Cannot add the image.");
}I looked over the image add form generated by Drupal, noting the fields' names and their default values. Then, we fill this with our info and send the data. Because we're using the same resource, $crl, we're still logged. In the end we check if the resulting url is still "node/add/image". If it is, then some data wasn't filled right and Drupal returned us to the node add page.
What's with that @ in the code?
"edit[image]"=>"@$file.jpg",edit[image] is an input of type file. By using @, we tell cURL to fetch the contents of that file and send them to the add script.
3. Example: Adding an user
$url = "http://www.example.com/admin/user/create";
curl_setopt($crl, CURLOPT_URL, $url);
$postdata = array(
"edit[name]"=>"newuser",
"edit[mail]"=>"newuser@example.com",
"edit[password]"=>"password",
"edit[notify]"=>1,
"op"=>"Submit",
"edit[form_id]"=>"user_register"
);
curl_setopt ($crl, CURLOPT_POSTFIELDS, $postdata);
$result=curl_exec($crl);
$headers = curl_getinfo($crl);
if ($headers['url'] == $url) {
die("Cannot add the image.");
}And that's basically it. Post any questions or suggestions to the forums or here.
