<?php
/**
 * bithub.net SDK for PHP
 *
 * ($id$)
 * 
 * @example
 * 
 * List all shares and files:
 * 
 * $pBithubApi = new BithubApi('email', 'password');
 * $pShares = $pBithubApi->getShares();
 *
 * // Iterate every share and retrieve files.
 * foreach ($pShares as $curShare) {
 *    echo '<h1>'.$curShare->getName.'</h1>';
 *    $files = $pBithubApi->listFiles($curShare->getId);    
 *    
 *    foreach ($files as $curFile) {
 *        echo '<a href="'.$curFile->getDownloadLink().'">'.$curFile->getName.'</a><br/>';        
 *    }
 * }
 * 
 * @version 1.1
 * @see http://bithub.net/api_howto
 * @author Marc Steinert <marc@bithub.net>
 * @copyright bithub.net 2008-2009
 */
class BithubApi {

    
/**
     * Url to the bithub.net main page, without trailing slash
     *
     * @var string
     */
    
const BASE_URL 'http://bithub.net';

    
/** @var string */
    
private $_username;

    
/** @var string */
    
private $_password;


    
/**
     * Constructor, loads user credentials.
     * 
     * @param string $username
     * @param string $password
     */
    
public function __construct($username$password) {
        
$this->_username $username;
        
$this->_password $password;
    }

    
/**
     * Lists all files in a bithub.net share.
     * 
     * @param int $shareId
     * @return array
     */
    
public function listFiles($shareId) {
        
$request =
            
'<request>
                <type>listfiles</type>
                <id>'
.(int) $shareId.'</id>
            </request>'
;
        
        
$response $this->dispatchApiCall('/'$request);
        
        
$files = array();
        
        if (
$response instanceof SimpleXMLElement) {
            foreach (
$response->file as $curFile) {
                
$files[] = new BithubFile($curFile);
            }
        }
        
        return 
$files;
    }
    
    
/**
     * Retrieves an array containing all bithub.net shares
     * 
     * @return array Array containing instances of <code>BithubShare</code>.
     */
    
public function getShares() {
        
$request =
            
'<request>
                <type>listshares</type>
            </request>'
;
            
        
$response $this->dispatchApiCall('/'$request);
        
        
$shares = array();
        
        foreach(
$response->share as $curShare) {
            
$shares[] = new BithubShare($curShare);
        }
        
        return 
$shares;
    }
    
    
/**
     * Sends API call to the bithub server.
     * 
     * @throws Exception
     * 
     * @param string $targetPath
     * @param string $xmlRequest
     * @return SimpleXMLElement
     */
    
protected function dispatchApiCall($targetPath$xmlRequest null) {
        
$header = array();
        
        
// Use basic HTTP authentication
        
$header[] = 'Authorization: Basic '.base64_encode($this->_username.':'.$this->_password);
        
        
$header[] = 'Content-type: text/xml';
        
        
$params = array(
            
'http' => array(
                
'method' => 'POST',
                
'header' => implode("\n"$header),
                
'content' => $xmlRequest
            
)
        );
        
        
// We dont rely on curl, because it won't let us write plain
        // POST data without named fields
        
$context stream_context_create($params);
        
        if ((
$fp fopen(self::BASE_URL.$targetPath'r'false$context))) {
            
$response '';
            
            while((
$row fgets($fp))) {
                
$response .= trim($row);
            }
            
            return new 
SimpleXMLElement($response);
        }
        
        return 
null;
    }
}


/**
 * Represents a share on the bithub.net webservice
 *
 */
class BithubShare {

    
/** @var int */
    
private $_id;
    
    
/** @var string */
    
private $_name;
    
    
    public function 
__construct(SimpleXMLElement $xmlElement) {
        
$this->_id = (int) $xmlElement->id;
        
$this->_name = (string) $xmlElement->name;
    }
    
    public function 
getId() {
        return 
$this->_id;
    }
    
    public function 
getName() {
        return 
$this->_name;
    }
}


/**
 * Represents a file on the bithub.net webservice.
 *
 */
class BithubFile {

    
/** @var int */
    
private $_id;
    
    
/** @var string */
    
private $_filename;
    
    
/** @var string */
    
private $_token;
    
    
/** @var string */
    
private $_lastModified;    
    
    
    
/**
     * Constructor, loads API response.
     *
     * @param SimpleXMLElement $xmlElement XML data returned by the API
     */
    
public function __construct(SimpleXMLElement $xmlElement) {
        
$this->_id = (int) $xmlElement->id;
        
$this->_filename = (string) $xmlElement->filename;
        
$this->_token = (string) $xmlElement->token;
        
$this->_lastModified = (string) $xmlElement->lastmodified;
    }
    
    
/**
     * Gets the full filename with extension.
     *
     * @return string
     */
    
public function getName() {
        return 
$this->_filename;
    }
    
    
/**
     * Retrieves a download link for the file.
     * 
     * @return string
     */
    
public function getDownloadLink() {
        return
            
BithubApi::BASE_URL.
            
'/?location=downloadfile&id='.$this->_id.
            
'&token='.$this->_token;
    }
}

?>