<?php
/***
* Simple php5 class to talk to Dada using its flash/xml feature
* http://dadamailproject.com/support/documentation-dada-2_10_16/email_subscription_form.pod.html
* Author:
* HdotNET www.capitalh.net
* Requirements:
* Pear HTTP_Request http://pear.php.net/package/HTTP_Request/
* Usage:
* $dada = new Dada();
* $dada->set_dada_url('http://www.example.com/cgi-bin/dada/mail.cgi');
* $dada->subscribe('someone@example.com','listname');
*/
class Dada{
	public $dada_url;
	public $dada_errors;
	public $errors = array();
	private $req;
	private $response;
	private $xml;

	public function __construct(){
		$this->dada_errors = array(
		'blacklisted'=>  'This email address has been closed',
		'closed_list'=> 'This list is closed',
		'invalid_email'=> 'The email address is invalid',
		'mx_lookup_failed'=>'Tghe MX lookup failed for that email address',
		'no_list'=>'No such list exists',
		'subscribed'=>'This address is already subscribed to the list',
		'not_subscribed'=>'This email address is not subscribed to this list',
		'settings_possibly_corrupted'=>'The setting are possible corrupted',
		'over_subscription_quota'=>'This list has reached its subscription quota',
		'already_sent_sub_confirmation'=>'The subscription confirmation email has already been sent',
		'already_sent_unsub_confirmation'=>'The unsubscription confirmation email has already been sent'
		);
		require_once('HTTP/Request.php');
        $this->req =& new HTTP_Request();
        $this->req->setMethod(HTTP_REQUEST_METHOD_GET);	
		$this->xml = new Xml();
	
	}
	public function set_dada_url($url)
	{
		$this->dada_url = $url;
		$this->req->setURL($this->dada_url);
	}
	public function subscribe($email,$list)
	{	
		$this->setArguments(array( "email" => $email, "list" => $list, "f" => 'subscribe_flash_xml'));
		if(!$this->send_request()){ // the request failed
			return false;
		}else{
			$this->xml->load_xml($this->response);
			$response = $this->xml->dom;
			if(!isset($response['subscription'])){ // that's weird.. the response doesnt contain the top level 'subscription' element
				$this->errors[] = 'Invalid response from Dada';
				return false; 
			}			
			if($response['subscription']['status'] == 1){
				return true;
			}else{ // dada says something is wrong
				$errors = $response['subscription']['errors'];	
				foreach($errors as $error){
					$this->errors[] = $this->dada_errors[$error];
				}
				return false;
			}
		}		
	}
	public function unsubscribe($email,$list)
	{
		$this->setArguments(array( "email" => $email, "list" => $list, "f" => 'unsubscribe_flash_xml'));
		if(!$this->send_request()){ // the request failed
			return false;
		}else{
			$this->xml->load_xml($this->response);
			$response = $this->xml->dom;
			if(!isset($response['unsubscription'])){ // that's weird.. the response doesnt contain the top level 'unsubscription' element
				// this can happen if you are using a very old version of dada.
				$this->errors[] = 'Invalid response from Dada';
				return false; 
			}
			if($response['unsubscription']['status'] == 1){
				return true;
			}else{ // dada says something is wrong
				$errors = $response['unsubscription']['errors'];	
				foreach($errors as $error){
					$this->errors[] = $this->dada_errors[$error];
				}
				return false;
			}
		}
	}
	private function setArguments($args)
	{
        $this->req->clearPostData();
		foreach ($args as $key => $data) {
			$this->req->addQueryString($key, $data);
		}	
	}
	private function send_request()
	{
		if ($this->req->sendRequest()) {
			$this->response = $this->req->getResponseBody();
			return true;
		}else{  // the PEAR HTTP_Request didn't work
			$this->errors[] = 'HTTP Request to '.$this->dada_url.' failed.';
			return false;
		}	
	}
}
/******
* this class lifted from here:
* http://uk2.php.net/manual/en/ref.xml.php#84758
* wolfon.AT-DoG.inbox.ru
*/
class Xml{
    private $parser;
    private $pointer;
    public $dom;
   
    public function __construct() {
    }
  	public function load_xml($data){

        $this->pointer =& $this->dom;
        $this->parser = xml_parser_create();
        xml_set_object($this->parser, $this);
        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
        xml_set_element_handler($this->parser, "tag_open", "tag_close");
        xml_set_character_data_handler($this->parser, "cdata");
        xml_parse($this->parser, $data);	
	
	}
    private function tag_open($parser, $tag, $attributes) {
        if (isset($this->pointer[$tag]['@attributes'])) {
            $content = $this->pointer[$tag];
            $this->pointer[$tag] = array(0 => $content);
            $idx = 1;
        } else if (isset($this->pointer[$tag]))
            $idx = count($this->pointer[$tag]);

        if (isset($idx)) {
            $this->pointer[$tag][$idx] = Array(
                '@idx' => $idx,
                '@parent' => &$this->pointer);
               $this->pointer =& $this->pointer[$tag][$idx];
        } else {
            $this->pointer[$tag] = Array(
                '@parent' => &$this->pointer);
            $this->pointer =& $this->pointer[$tag];
        }
        if (!empty($attributes))
            $this->pointer['@attributes'] = $attributes;
    }

    private function cdata($parser, $cdata) {
           $this->pointer['@data'] = $cdata;
    }

    private function tag_close($parser, $tag) {
        $current = & $this->pointer;
        if (isset($this->pointer['@idx']))
            unset($current['@idx']);
       
        $this->pointer = & $this->pointer['@parent'];
       
          unset($current['@parent']);
           if (isset($current['@data']) && count($current) == 1)
               $current = $current['@data'];
           else if (empty($current['@data'])||$current['@data']==0)
               unset($current['@data']);
    }
}

?>