handle = curl_init(); $this->set_base_url($base_url); } /** * Utility function to set the client's base-url. * * This is needed because on some installations we use SSL, and cURL changes * POST requests to GET after redirects. */ public function set_base_url($base_url) { $this->curlOpen($base_url); // Do *not* follow redirects - we want to analyse the server's response. curl_setopt($this->handle, CURLOPT_FOLLOWLOCATION, FALSE); $this->curlExecute(); $info = curl_getinfo($this->handle); if ($info['http_code'] == 301) { // Redirect detected // Get the headers & extract the goto - URL $headers = get_headers($info['url']); $location = ""; foreach( $headers as $value ) { if ( substr( strtolower($value), 0, 9 ) == "location:" ) { $redirected_base_url= trim( substr( $value, 9, strlen($value))); // Use the found values as base-url. $this->base_url= $redirected_base_url; return; } } } // Default: use the provided url $this->base_url = $base_url; } public function close() { curl_close($this->handle); unset($this->handle); } static public function asDom($content) { $html = DOMDocument::loadHTML($content); if (is_null($html)) { throw new Exception("Could not parse HTML at url ". $url); } return simplexml_import_dom($html); } public function getDom($url) { $content = $this->get($url); return self::asDom($content); } public function get($url) { $this->curlOpen($url); curl_setopt($this->handle, CURLOPT_HTTPGET, True); return $this->curlExecute(); } public function post($url, $params) { $this->curlOpen($url); curl_setopt($this->handle, CURLOPT_POST, count($params)); curl_setopt($this->handle, CURLOPT_POSTFIELDS, DrupalUserAgent::paramString($params)); return $this->curlExecute(); } public static function paramString($params) { $post = array(); foreach($params as $field => $value) { $post[] = urlencode($field) .'='. urlencode($value); } return implode($post, '&'); } public function curlOpen($url) { // echo $url ."\n"; $options = array( CURLOPT_URL => $this->absoluteUrl($url), //CURLOPT_VERBOSE => TRUE, CURLOPT_COOKIEJAR => NULL, // accepts session cookie, just not on disk CURLOPT_TIMEOUT => 300, CURLOPT_FOLLOWLOCATION => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_SSL_VERIFYPEER => FALSE, CURLOPT_USERAGENT => 'drupal-user-agent'); curl_setopt_array($this->handle, $options); } public function setCookies($cookies) { curl_setopt($this->handle, CURLOPT_COOKIE, DrupalUserAgent::paramString($params)); } public function curlExecute() { $content = curl_exec($this->handle); $err_id = curl_errno($this->handle); if ($err_id != 0) { throw new Exception(curl_error($this->handle)); } return $content; } public function absoluteUrl($url) { if (empty($url)) { return $this->base_url; } if (empty($this->base_url) || strpos($url, $this->base_url) === 0) { return $url; } return $this->base_url . $url; } } class DrupalFormLoader { private $form; private $params = array(); public function __construct($form) { $this->form = $form; } public static function findById($dom, $id) { $elems = $dom->elements->xpath("//form[@id='" . $id ."']"); return empty($elems) ? NULL : new DrupalFormLoader($elems[0]); } public static function findBySubmitValue($dom, $submit) { $elems = $dom->elements->xpath("//input[@type='submit' and @value='" . $submit ."']"); if (!$elems) { return NULL; } foreach ($elems as $elem) { $form = $elem->xpath('ancestor::form'); if (!empty($form)) { return new DrupalFormLoader($form); } } } public function setValue($name, $value) { $this->params[$name] = $value; } public function getAction() { return (string)$this->form['action']; } public function getParams() { // surely there is more types, only understand these at the moment $elements = $this->form->xpath("descendant::input|descendant::textarea"); foreach ($elements as $element) { // SimpleXML objects need string casting all the time. $name = (string)$element['name']; // ignore preset parameters if (empty($name) || array_key_exists($name, $this->params)) { continue; } switch ($element->getName()) { case 'input': $type = $element['type']; switch ($type) { case 'radio': case 'checkbox': if (!isset($element['checked'])) { break; } // Deliberate no break. default: $value = isset($element['value']) ? (string)$element['value'] : ''; break; } break; case 'textarea': $value = (string)$element; break; case 'select': throw new Exception('select element not supported yet'); } $this->params[$name] = $value; } return $this->params; } } ?>