Subversion Repositories Plazes

[/] [Ovi/] [class.ovi.php] - Rev 141

Compare with Previous | Blame | View Log

<?php
/**
  * ShareOnOvi - A PHP class for interacting with Nokia's "Share on Ovi" service.
  *
  * The Share on Ovi service from Nokia, a website and related applications that allow
  * for media sharing, provides the facility to upload new items using the Atom
  * Publishing Protocol (APP).  This PHP class implements a subset of the APP to
  * allow new JPEG images (only, for the time being) to by uploaded to Share on Ovi
  * programatically.
  * 
  * Requirements for use:
  * 
  *  - PHP 5 or greater
  *  - class.wsse.php (available from http://www.dentedreality.com.au/phpatomapi/)
  *  - a Share on Ovi account
  *
  * To do:
  *
  *  - additional error checking at possible failure points
  *  - support additional media types (currently supports only JPEG)
  *  - additional functionality to support edit of existing media
  *
  * Usage example:
  *
  *   require_once 'class.ovi.php';
  *   $son = new ShareOnOvi('username','password');
  *   $son->Upload("~/images/test.jpg","My Test Image","A picture of my dog",array("dog","animal"),"public");
  *     
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
  * your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  *
  * @version 1.2, July 13, 2008
  * @link http://ruk.ca/w/index.php/Share_on_Ovi_API Documentation
  * @link http://share.ovi.com/ Share on Ovi website
  * @link http://www.ietf.org/rfc/rfc5023.txt Atom Publishing Protocol - RFC 5023
  * @author Peter Rukavina <peter@rukavina.net>
  * @copyright Copyright &copy; 2008, Reinvented Inc.
  * @license http://www.fsf.org/licensing/licenses/gpl.txt GNU Public License
  */

class ShareOnOvi {
    
    private 
$userAgent "ShareOnOvi PHP/1.0";
    private 
$endPoint "http://share.ovi.com/api/atom/1.0/";
    
    
/** 
    * Creates a ShareOnOvi object
    * @param string $username the Share on Ovi username
    * @param string $password the Share on Ovi password
    */
    
function __construct($username$password) {
        
$this->username $username;
        
$this->password $password;
        
$this->xmlskeleton $this->makeMetadataSkeleton();
    }

    
/**
    * Uploads a file to Share On Ovi.
    * @param string $filename the filename (complete path) of the file to upload (supports JPEG images only right now)
    * @param string $title the title to give the image on Share on Ovi
    * @param string $summary the summary ("description") to give the image on Share on Ovi
    * @param array $tags the tags to give the image on Share on Ovi
    * @param string $channel the channel to upload to (i.e. "mymedia" or "public") - must already exist
    * @return string the URL of the Share on OVI object
    */    
    
function Upload($filename,$title,$summary,$tags,$channel) {

        
// Check to see if the file we want to upload actually exists.
        
if (!file_exists($filename) and !($this->is_url($filename))) {
            die(
"ERROR: The file '$filename' does not exist. You must pass the complete path.\n");
        }

        
// We need class.wsse.php to package up the WSSE authentication header.
        
require_once("class.wsse.php");

        
// Create a new cURL object.
        
$ch curl_init($this->endPoint $this->username "." $channel);

        
// Construct a WSSE header array from the username and password.
        
$WSSE = new WSSE($this->username,$this->password);
        
$this->WSSE $WSSE->get_header(true);

        
// The headers for the HTTP POST.
        
$headers = array("Content-Type: image/jpeg",
                         
"User-Agent: " $this->userAgent);

        
// Add the WSSE headers into the mix.
        
$headers array_merge($this->WSSE,$headers);

        
// Grab the file we're going to upload (requires the complete path).
        
$upload file_get_contents($filename);

        
// Add the headers to the cURL object.
        
curl_setopt($chCURLOPT_HTTPHEADER$headers);

        
// Don't return the headers as part of the response.
        
curl_setopt($chCURLOPT_HEADER0);
        
        
// Return the response as the return vaalue of the curl_exec.
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
        
// This is just a straight binary POST, not a key-value pair POST, so we use a custom request.
        
curl_setopt($chCURLOPT_CUSTOMREQUEST"POST");

        
// Set the binary data as the POST payload.
        
curl_setopt($chCURLOPT_POSTFIELDS$upload);
        
        
// Do the actual cURL magic.
        
$output curl_exec($ch);   
        
        
// Close the cURL object.  
        
curl_close($ch);

        
// If we got back a simple 'Authentication failed.' response, then we exit with an error message.
        
if ($output == "Authentication failed.") {
            die(
"ERROR: Share on Ovi authentication failed.  Check the username and password.\n");
        }

        
// Take the response we got from cURL as XML and turn it into a PHP object.
        
$response = new SimpleXMLElement($output);
        
        
// Look for the links with attributes of 'edit' (the endpoint for PUTing metadata) and 'alternate' (the URL for the new object on OVI)
        
foreach($response->link as $key => $link) {
            
$attrs $link->attributes();
            if (
$attrs['rel'] == 'edit') {
                
$editURL $attrs['href'];
            }
            else if (
$attrs['rel'] == 'alternate') {
                
$objectURL $attrs['href'];
            }
        }

        
// If we didn't get a link in the XML returned to PUT the metadata, then something went wrong and we exit.
        
if ($editURL == '') {
            die(
"ERROR: No endpoint returned from Share on Ovi to PUT image metadata.\n");
        }

        
// Contruct a new SimpleXML object, using the 'metadata-skeleton.xml' file as a template.
        
$xml = new SimpleXMLElement($this->xmlskeleton);

        
// Add image title element, with attribute type=text.
        
$xml_title $xml->addChild('title',$title);
        
$xml_title->addAttribute("type","text");

        
// Add image summary element.
        
$xml_summary $xml->addChild('summary',$summary);

        
// Add a category element, setting privacy to public.
        
$xml_term $xml->addChild('category',null);
        
$xml_term->addAttribute("term","public");
        
$xml_term->addAttribute("scheme","http://schemas.nokia.com/onlinesharing/2006/category#privacylevels");

        
// Add category elements for each tag.
        
foreach($tags as $key => $value) {
            
$xml_tag $xml->addChild('category',null);
            
$xml_tag->addAttribute("term",$value);
            
$xml_tag->addAttribute("scheme","http://schemas.nokia.com/onlinesharing/2006/category#tags");
        }
        
        
// Convert the SimpleXML object into XML text.
        
$xml_request $xml->asXML();
        
$content_length strlen($xml_request);
        
        
// Create a new cURL object.
        
$ch curl_init($editURL);

        
// Construct a WSSE header array from the username and password (each request demands a brand-new WSSE header).
        
$WSSE = new WSSE($this->username,$this->password);
        
$this->WSSE $WSSE->get_header(true);

        
// The headers for the HTTP POST.
        
$headers = array("Content-Type: application/atom+xml; charset=utf-8",
                         
"Content-Length: " $content_length,
                         
"User-Agent: " $this->userAgent);

        
// Add the WSSE headers into the mix.
        
$headers array_merge($this->WSSE,$headers);

        
// Add the headers to the cURL object.
        
curl_setopt($chCURLOPT_HTTPHEADER$headers);

        
// Don't return the headers as part of the response.
        
curl_setopt($chCURLOPT_HEADER0);

        
// Return the response as the return vaalue of the curl_exec.
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);

        
// This is going to be an HTTP PUT (using CURLOPT_CUSTOMREQUEST because CURLOPT_PUT caused issues with headers)
        
curl_setopt($chCURLOPT_CUSTOMREQUEST"PUT");

        
// Set the binary data as the PUT payload.
        
curl_setopt($chCURLOPT_POSTFIELDS$xml_request);
        
        
// Do the actual cURL magic.
        
$output curl_exec($ch);     

        
// Close the cURL object.  
        
curl_close($ch);
        
        
// Return the Share on Ovi URL of the object we created.
        
return $objectURL;
    }

    
/**
    * Returns the skelton XML required to PUT metadata.
    * @return string XML skeleton
    */
    
function makeMetadataSkeleton() {
        
$xml = <<<END
<?xml version="1.0" encoding="utf-8" ?>
<entry xmlns="http://www.w3.org/2005/Atom"
        xmlns:atom03="http://purl.org/atom/ns#"
        xmlns:thr="http://purl.org/syndication/thread/1.0"
        xmlns:georss="http://www.georss.org/georss"
        xmlns:nokia="http://schemas.nokia.com/onlinesharing/2006">
<atom03:generator>ShareOnOvi PHP/1.0</atom03:generator>
</entry>

END;
        return 
$xml;
    }
    
    
/**
     * Sanity check, is it really an URL?
     * From http://crunchbang.org/wiki/php-function-isurl/
     */
    
function is_url($url){
        
$url substr($url,-1) == "/" substr($url,0,-1) : $url;
        if ( !
$url || $url=="" ) return false;
        if ( !( 
$parts = @parse_url$url ) ) ) return false;
        else {
            if ( 
$parts[scheme] != "http" && $parts[scheme] != "https" && $parts[scheme] != "ftp" && $parts[scheme] != "gopher" ) return false;
            else if ( !
eregi"^[0-9a-z]([-.]?[0-9a-z])*.[a-z]{2,4}$"$parts[host], $regs ) ) return false;
            else if ( !
eregi"^([0-9a-z-]|[_])*$"$parts[user], $regs ) ) return false;
            else if ( !
eregi"^([0-9a-z-]|[_])*$"$parts[pass], $regs ) ) return false;
            else if ( !
eregi"^[0-9a-z/_.@~-]*$"$parts[path], $regs ) ) return false;
            else if ( !
eregi"^[0-9a-z?&=#,]*$"$parts[query], $regs ) ) return false;
        }
        return 
true;
    }
}

Compare with Previous | Blame | View Log