• 0

PHP + Picasa


Question

I upload my photos via Picasa to Picasa Web Albums (powered by Google). I am looking to pull off my photos and display them on my site.

I'd like to do this using PHP. I've looked through the API provided and have to admit I think they are too complicated for my task - they all want me to login, etc - assuming I am going to be uploading and so on - I simply want to be able to query an API to get, for example:

List of albums

Photos in an album

Can anyone please give me some pointers or provide some example code?

Many thanks

Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/
Share on other sites

14 answers to this question

Recommended Posts

  • 0

OK, I have gotten so far but am stuck - and it's probably down to my understanding of XML.

Anyhow, I am trying to consume this feed: http://picasaweb.google.com/data/feed/api/user/njlouch

My code is as such:

<?php
$xmlPath = "http://picasaweb.google.com/data/feed/api/user/njlouch/albumid/5243351093451015857";
if (!$myxml=simplexml_load_file($xmlPath)){
	echo 'Error reading the XML file';
} else{
	foreach($myxml->entry as $track){
		echo('<b><a href="'.$track->id.'">'.$track->title.'</a></b>');
		echo('<b>'.$track->summary.'</b>');
		echo('<img src="'.$track->content->href.'">');


	}
}
?>

All I want to do at this stage is to access the image name, description and the image itself. The first two are simple, but it's the image I am stuck at. But ultimately I want to show for each entry:

- published

- title

- summary

- media:thumbnail

- media:content

This is the content of the feed:

<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:exif='http://schemas.google.com/photos/exif/2007' xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#' xmlns:gml='http://www.opengis.net/gml' xmlns:georss='http://www.georss.org/georss' xmlns:photo='http://www.pheed.com/pheed/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gphoto='http://schemas.google.com/photos/2007'>
	<id>http://picasaweb.google.com/data/feed/api/user/njlouch/albumid/5243351093451015857</id>
	<updated>2008-09-07T18:40:14.000Z</updated>
	<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#album'/>
	<title type='text'>20080907</title>
	<subtitle type='text'></subtitle>
	<rights type='text'>public</rights>
	<icon>http://lh6.ggpht.com/njlouch/SMQgCf3NxrE/AAAAAAAAAEQ/KtOgOMDMgho/s160-c/20080907.jpg</icon>
	<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://picasaweb.google.com/data/feed/api/user/njlouch/albumid/5243351093451015857'/>
	<link rel='alternate' type='text/html' href='http://picasaweb.google.com/njlouch/20080907'/>
	<link rel='http://schemas.google.com/photos/2007#slideshow' type='application/x-shockwave-flash' href='http://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&RGB=0x000000&feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fnjlouch%2Falbumid%2F5243351093451015857%3Falt%3Drss'/>
	<link rel='http://schemas.google.com/photos/2007#report' type='text/html' href='http://picasaweb.google.com/lh/reportAbuse?uname=njlouch&aid=5243351093451015857'/>
	<link rel='self' type='application/atom+xml' href='http://picasaweb.google.com/data/feed/api/user/njlouch/albumid/5243351093451015857?start-index=1&max-results=1000'/>
	<author>
		<name>Niki</name>
		<uri>http://picasaweb.google.com/njlouch</uri>
	</author>
	<generator version='1.00' uri='http://picasaweb.google.com/'>Picasaweb</generator>
	<openSearch:totalResults>2</openSearch:totalResults>
	<openSearch:startIndex>1</openSearch:startIndex>
	<openSearch:itemsPerPage>1000</openSearch:itemsPerPage>
	<gphoto:id>5243351093451015857</gphoto:id>
	<gphoto:name>20080907</gphoto:name>
	<gphoto:location></gphoto:location>
	<gphoto:access>public</gphoto:access>
	<gphoto:timestamp>1220747072000</gphoto:timestamp>
	<gphoto:numphotos>2</gphoto:numphotos>
	<gphoto:user>njlouch</gphoto:user>
	<gphoto:nickname>Niki</gphoto:nickname>
	<gphoto:commentingEnabled>true</gphoto:commentingEnabled>
	<gphoto:commentCount>0</gphoto:commentCount>
	<gphoto:allowPrints>true</gphoto:allowPrints>
	<gphoto:allowDownloads>true</gphoto:allowDownloads>
	<entry>
		<id>http://picasaweb.google.com/data/entry/api/user/njlouch/albumid/5243351093451015857/photoid/5243351093575526146</id>
		<published>2008-09-07T18:40:10.000Z</published>
		<updated>2008-09-07T18:40:10.000Z</updated>
		<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#photo'/>
		<title type='text'>012431.jpg</title>
		<summary type='text'></summary>
		<content type='image/jpeg' src='http://lh4.ggpht.com/njlouch/SMQgCgU5pwI/AAAAAAAAAEE/lB3WuZX9bQ4/012431.jpg'/>
		<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://picasaweb.google.com/data/feed/api/user/njlouch/albumid/5243351093451015857/photoid/5243351093575526146'/>
		<link rel='alternate' type='text/html' href='http://picasaweb.google.com/lh/photo/7I4RFVbODHoFcaenV8xFXQ'/>
		<link rel='self' type='application/atom+xml' href='http://picasaweb.google.com/data/entry/api/user/njlouch/albumid/5243351093451015857/photoid/5243351093575526146'/>
		<link rel='http://schemas.google.com/photos/2007#report' type='text/html' href='http://picasaweb.google.com/lh/reportAbuse?uname=njlouch&aid=5243351093451015857&iid=5243351093575526146'/>
		<gphoto:id>5243351093575526146</gphoto:id>
		<gphoto:version>1220812810331000</gphoto:version>
		<gphoto:position>1.04209837E9</gphoto:position>
		<gphoto:albumid>5243351093451015857</gphoto:albumid>
		<gphoto:width>640</gphoto:width>
		<gphoto:height>480</gphoto:height>
		<gphoto:size>41233</gphoto:size>
		<gphoto:client>picasa</gphoto:client>
		<gphoto:checksum>760c1fda</gphoto:checksum>
		<gphoto:timestamp>1220747072000</gphoto:timestamp>
		<exif:tags>
			<exif:imageUniqueID>1e8b8741694f39bc7380e1222fbd3fe1</exif:imageUniqueID>
		</exif:tags>
		<gphoto:commentingEnabled>true</gphoto:commentingEnabled>
		<gphoto:commentCount>0</gphoto:commentCount>
		<media:group>
			<media:title type='plain'>012431.jpg</media:title>
			<media:description type='plain'></media:description>
			<media:keywords></media:keywords>
			<media:content url='http://lh4.ggpht.com/njlouch/SMQgCgU5pwI/AAAAAAAAAEE/lB3WuZX9bQ4/012431.jpg' height='480' width='640' type='image/jpeg' medium='image'/>
			<media:thumbnail url='http://lh4.ggpht.com/njlouch/SMQgCgU5pwI/AAAAAAAAAEE/lB3WuZX9bQ4/s72/012431.jpg' height='54' width='72'/>
			<media:thumbnail url='http://lh4.ggpht.com/njlouch/SMQgCgU5pwI/AAAAAAAAAEE/lB3WuZX9bQ4/s144/012431.jpg' height='108' width='144'/>
			<media:thumbnail url='http://lh4.ggpht.com/njlouch/SMQgCgU5pwI/AAAAAAAAAEE/lB3WuZX9bQ4/s288/012431.jpg' height='216' width='288'/>
			<media:credit>Niki</media:credit>
		</media:group>
	</entry>
	<entry>
		<id>http://picasaweb.google.com/data/entry/api/user/njlouch/albumid/5243351093451015857/photoid/5243351114783303842</id>
		<published>2008-09-07T18:40:14.000Z</published>
		<updated>2008-09-07T18:40:14.000Z</updated>
		<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#photo'/>
		<title type='text'>012448.jpg</title>
		<summary type='text'></summary>
		<content type='image/jpeg' src='http://lh5.ggpht.com/njlouch/SMQgDvVOqKI/AAAAAAAAAEM/-Egc7UiyN9Q/012448.jpg'/>
		<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://picasaweb.google.com/data/feed/api/user/njlouch/albumid/5243351093451015857/photoid/5243351114783303842'/>
		<link rel='alternate' type='text/html' href='http://picasaweb.google.com/lh/photo/VhQPN7Sc63O7porpugkfnQ'/>
		<link rel='self' type='application/atom+xml' href='http://picasaweb.google.com/data/entry/api/user/njlouch/albumid/5243351093451015857/photoid/5243351114783303842'/>
		<link rel='http://schemas.google.com/photos/2007#report' type='text/html' href='http://picasaweb.google.com/lh/reportAbuse?uname=njlouch&aid=5243351093451015857&iid=5243351114783303842'/>
		<gphoto:id>5243351114783303842</gphoto:id>
		<gphoto:version>1220812814313000</gphoto:version>
		<gphoto:position>1.0421024E9</gphoto:position>
		<gphoto:albumid>5243351093451015857</gphoto:albumid>
		<gphoto:width>640</gphoto:width>
		<gphoto:height>480</gphoto:height>
		<gphoto:size>41342</gphoto:size>
		<gphoto:client>picasa</gphoto:client>
		<gphoto:checksum>760e3fda</gphoto:checksum>
		<gphoto:timestamp>1220747089000</gphoto:timestamp>
		<exif:tags>
			<exif:imageUniqueID>2ff7ea92c91f6a0d6e8000b92655c836</exif:imageUniqueID>
		</exif:tags>
		<gphoto:commentingEnabled>true</gphoto:commentingEnabled>
		<gphoto:commentCount>0</gphoto:commentCount>
		<media:group>
			<media:title type='plain'>012448.jpg</media:title>
			<media:description type='plain'></media:description>
			<media:keywords></media:keywords>
			<media:content url='http://lh5.ggpht.com/njlouch/SMQgDvVOqKI/AAAAAAAAAEM/-Egc7UiyN9Q/012448.jpg' height='480' width='640' type='image/jpeg' medium='image'/>
			<media:thumbnail url='http://lh5.ggpht.com/njlouch/SMQgDvVOqKI/AAAAAAAAAEM/-Egc7UiyN9Q/s72/012448.jpg' height='54' width='72'/>
			<media:thumbnail url='http://lh5.ggpht.com/njlouch/SMQgDvVOqKI/AAAAAAAAAEM/-Egc7UiyN9Q/s144/012448.jpg' height='108' width='144'/>
			<media:thumbnail url='http://lh5.ggpht.com/njlouch/SMQgDvVOqKI/AAAAAAAAAEM/-Egc7UiyN9Q/s288/012448.jpg' height='216' width='288'/>
			<media:credit>Niki</media:credit>
		</media:group>
	</entry>
</feed>

Can anyone help please?

Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/#findComment-589813858
Share on other sites

  • 0

Well, to be honest its the name spaces which are throwing you off here. Name spaces are, IMO a real PIA for such small responses.

This is what I have, I was tasked to create an object that would take namespaced XML and remove all occurrences of the namespace.

It works, in fact, it works really well....I've extended the DOMDocument as to allow easier manipulation with it's methods.

I've tested it on internal, Youtube and Yahoo namespaced XML and it works a treat, but there's still work to be done I think.

Try it out with my blessings.

Class.NamespaceNulledXMLDocument.php

<?php
/**
 * @author		 Anthony David Sterling
 * 
 * @copyright	Anthony David Sterling
 * 
 * @version	 1.0
 * 
 * @desc		Removes namespace prefixes
 *				 programmatically based on the 
 *				 declared namespaces contained
 *				 within the document itself.
 * 
 * @todo		
 */
Class NamespaceNulledXMLDocument Extends DOMDocument
{
	/**
	 * @var		Boolean		Indicates whether we found any namespaces to remove.
	 */
	public $foundNamespaces = false;

	/**
	 * @var		Array		Holds all namespaces we found and processed.
	 */
	public $removedNamespaces = array();

	/**
	 * @param	String	$sXML	An XML document in string form.
	 * @return	 Void
	 */
	public function __construct( $sXML )
	{
		//--> Call the DOMDocument constructor to instantiate.
		parent::__construct();
		//--> Load our 'cleaned' XML into the DOMDocument.
		parent::loadXML( self::removeNamespaces($sXML) );
	}

	/**
	 * @param	String	$sXML	An XML document in string form.
	 * @return	String
	 */
	private function removeNamespaces( $sXML )
	{
		//--> Collecting all 'declared' namespace prefixes from within the XML document itself.
		$aNamespaces = ( preg_match_all( '/(?<=xmlns:).*?(?==)/' , $sXML , $aMatches , PREG_PATTERN_ORDER ) ) ? $aMatches[0] : array();
		//--> Before continuing, we'll check if we actually have any prefixes to remove.
		if( count($aNamespaces) > 0 )
		{
			//--> Logging the fact we found some namespaces to remove.
			$this->foundNamespaces = true;
			//--> Walking through each of the matched namespace prefixes and removing the prefix from every element.
			foreach ( $aNamespaces as $sNamespace )
			{
				//--> Log the namespace we are processing.
				$this->removedNamespaces[] = $sNamespace;
				//--> Replace any node with a namespace.
				$sXML =  preg_replace( "%(?<=<|</){$sNamespace}:%" , '' , $sXML );
				//--> Replace any attribute with a namespace.
				$sXML =  preg_replace( "/(?<=\\s){$sNamespace}:(?=.*?=\".*?\")/" , '' , $sXML );
			}
			//--> Return the new, clean, all singing, all dancing namespace nulled XML.
			return $sXML;
		}
		else
		{
			//--> Hmm, no namespaces to remove, so we'll just return the original XML that was supplied.
			return $sXML;
		}
	}
}
?>

Usage.php

<?php
//--> Load the class.
require_once( 'class.NamespaceNulledXMLDocument.php' );
//--> Obtain the namespaced XML.
$sXMLData = @file_get_contents('sample.xml');
//--> Create a NamespaceNulledXMLDocument, passing it the namespaced XML.
$oXML = new NamespaceNulledXMLDocument( $sXMLData );
//--> Using DOMDocument methods, format the output.
$oXML->formatOutput = true;
//--> Output the XML.
echo $oXML->saveXML();
?>

Enjoy!

SilverB.

Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/#findComment-589820242
Share on other sites

  • 0

Please excuse m noobishness... Is this correct?

<?php
//--> Load the class.
require_once( 'class.NamespaceNulledXMLDocument.php' );
//--> Obtain the namespaced XML.
$sXMLData = @file_get_contents('localfeed.xml');
//--> Create a NamespaceNulledXMLDocument, passing it the namespaced XML.
$oXML = new NamespaceNulledXMLDocument( $sXMLData );
//--> Using DOMDocument methods, format the output.
$oXML->formatOutput = true;
//--> Output the XML.
//echo $oXML->saveXML();
$myXML = $oXML->saveXML();
foreach($myXML>entry as $track){
	echo('<b><a href="'.$track->id.'">'.$track->title.'</a></b>');
	echo('<b>'.$track->summary.'</b>');
	echo('<img src="'.$track->content->href.'">');
}
?>

Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/#findComment-589840828
Share on other sites

  • 0

Here you go Nik, a quick demonstration for you.

<?php

require_once('class.NamespaceNulledXMLDocument.php');

$sData = @file_get_contents('localFeed.xml');

$oDocument = simplexml_import_dom( new NamespaceNulledXMLDocument( $sData ) );

echo sprintf("<h1>Album %s by %s</h1>\r\n",(String)$oDocument->name,(String)$oDocument->user);
echo '<hr />';

foreach ($oDocument->entry as $oEntry)
{
	echo sprintf("\r\n<h2>%s</h2>\r\n",(String)$oEntry->title);
	echo '<ul>';
	echo sprintf("<li>%s: %s</li>\r\n",'Height',(Integer)$oEntry->height);
	echo sprintf("<li>%s: %s</li>\r\n",'Width',(Integer)$oEntry->width);
	echo sprintf("<li>%s: %s bytes.</li>\r\n",'Size',(Integer)$oEntry->size);
	echo "</ul>\r\n";
	echo sprintf('<a href="%s" title="%s" target="_blank">Download</a>',(String)$oEntry->content['src'],(String)$oEntry->title);
}

?>

I've used the sample XML you provided in post #4 as a base.

I've basically, obtained the XML data (a local file called localFeed.xml), then passed that data to my class which creates an object with all the name spaces removed. We then pass that object to the simplexml_import_dom() function, which converts the DOM Document to a SimpleXML object for easier access.

We can now use any of the SimpleXML functions on our object ($oDocument).

Then we just iterate through the entries delivering the required data as needed.

Just so you're aware, you will unable to use the image paths supplied by the feed to embed images on another site. Google / Picasa deliver headers to the requesting agent to force download the image.

I guess this is to stop people doing what you are attempting.

You could bypass these headers, but that would be another lesson!

Feel free to pester me for advice.

SilverB.

Edited by SilverBulletUK
Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/#findComment-589847274
Share on other sites

  • 0

Thank you so much.

With reference to your header sorting script - Please see above link - am getting an error.

Fatal error: Call to undefined function curl_init() in C:\wamp\www\displaypic.php on line 3

Sorry - didn't enable CURL!

Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/#findComment-589848376
Share on other sites

  • 0

You don't have cURL installed, try this.

demo.php

<?php
require_once('class.NamespaceNulledXMLDocument.php');
$sData = @file_get_contents('localFeed.xml');
$oDocument = simplexml_import_dom( new NamespaceNulledXMLDocument( $sData ) );
echo sprintf("<h1>Album %s by %s</h1>\r\n",(String)$oDocument->name,(String)$oDocument->user);
echo "<hr />\r\n";
foreach ($oDocument->entry as $oEntry)
{
	echo sprintf("<h2>%s</h2>\r\n",(String)$oEntry->title);
	echo '<ul>';
	echo sprintf("<li>%s: %s</li>\r\n",'Height',(Integer)$oEntry->height);
	echo sprintf("<li>%s: %s</li>\r\n",'Width',(Integer)$oEntry->width);
	echo sprintf("<li>%s: %s bytes.</li>\r\n",'Size',(Integer)$oEntry->size);
	echo "</ul>\r\n";
	echo sprintf('<img src="picasaImage.php?picasaImage=%s" alt="%s" />',base64_encode((String)$oEntry->content['src']),(String)$oEntry->title);
}
?>

picasaImage.php

<?php
if( isset($_GET['picasaImage']) )
{
	$sImageURL = base64_decode( $_GET['picasaImage'] );
	if( $sImageData = @file_get_contents($sImageURL) )
	{
		header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
		header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
		header( 'Content-Type: image/jpg' );
		header( 'Cache-Control: no-store, no-cache, must-revalidate' );
		header( 'Cache-Control: post-check=0, pre-check=0', false );
		header( 'Pragma: no-cache' );
		echo $sImageData;
		exit;
	}
}
exit;
?>

Place both of those on your server, it should do the trick.

SilverB.

Edited by SilverBulletUK
Link to comment
https://www.neowin.net/forum/topic/666422-php-picasa/#findComment-589848420
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Surprise! We still can't get it right. With the current state of AI, the crappy software, the huge mega-corporations that back all of these idiot things, I think we are a very long way away from SAE Level 5. I, for one, will never get in one.
    • Nice. September/October GA?! I'll keep following it, but won't install any preview or beta versions.
    • Wow, that could have been dangerous, certainly not ready for these things. They have to be 100% or pretty well close to it. Not that I will see one i doubt, never mind ride in one, they may have them in London, but I doubt they will come to where I live.
    • Nothing kills CMF Phone 2 Pro's successor due to rising memory prices by Hamid Ganji Storage and RAM prices have been rising over the past year, leading to a significant increase in the cost of electronics for customers around the world. Many companies are now revising their plans for upcoming devices due to higher component costs and overall production expenses. CMF is the latest company to cancel the successor to one of its best-selling phones due to rising memory prices. CMF is a sub-brand of Nothing and focuses on making budget smartphones for growing markets. The brand launched the CMF Phone 2 Pro last year with some eye-catching specifications and an affordable price. While many customers may have been waiting for a successor this year, one of the company’s executives has announced that CMF will not release a new smartphone this year. And AI is to blame. As Nothing co-founder Akis Evangelidis announced on X, the company has been working on a successor to the CMF Phone 2 Pro, but with current memory prices, it cannot “build a phone that feels like a genuine step forward at a price that makes sense for CMF.” So, no new CMF phone will be launched this year. Meanwhile, Evangelidis said the company still has several new products in the pipeline, including some in entirely new categories. He added that the Nothing brand will also continue launching new products through 2026. Budget smartphones are among the first victims of the surge in RAM and memory prices, as they have become more expensive to build. The sharp increase in memory costs could also reshape the traditional price ranges associated with budget phones. Apple CEO Tim Cook also recently said that price increases for some of the company’s products are unavoidable because RAM and memory have become significantly more expensive this year. Analysts estimate that the base price of the upcoming iPhone 18 Pro could rise to $1,399 due to current market shortages.
    • Nudge me when they bring back hardware audio acceleration so I can get my EAX 5 back. We've evolved graphics to real-time path tracing, but regressed audio some 15 years back in time with this stupid software audio stack.
  • Recent Achievements

    • Collaborator
      ryansurfer98 went up a rank
      Collaborator
    • Week One Done
      Eurosoft10 earned a badge
      Week One Done
    • One Month Later
      Eurosoft10 earned a badge
      One Month Later
    • One Year In
      Skeet Campbell earned a badge
      One Year In
    • One Month Later
      Sharbel earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      541
    2. 2
      +Edouard
      187
    3. 3
      Michael Scrip
      78
    4. 4
      PsYcHoKiLLa
      75
    5. 5
      Steven P.
      71
  • Tell a friend

    Love Neowin? Tell a friend!