Displaying 5 latest thumbnails from public flickr api using atom_1 and php
Asked Answered
I

1

0

Im trying to display the latest 5 images from:

http://api.flickr.com/services/feeds/photos_public.gne

with the tag "cars" and then output the latest 5 thumbnails into a blank html document as a type of gallery.

This is as far as i have gotten:

<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();

$request->setUrl('http://api.flickr.com/services/feeds/photos_public.gne');
$request->setMethod(HTTP_Request2::METHOD_GET);
$url = $request->getUrl();
$url->setQueryVariable('tags', 'cars');
$url->setQueryVariable('tagmode', 'any');
$url->setQueryVariable('format', 'atom_1');

try {
   $response = $request->send(); 
   if (200 == $response->getStatus()) {             
   $body = $response->getBody();
} else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
         $response->getReasonPhrase();
}
} catch (HTTP_Request2_Exception $e) {
   echo 'Error: ' . $e->getMessage();
}


$DOM = new SimpleXMLElement($body);

?>

I don't know if this is correct and i'm not sure how to go about displaying it in html.

Izy answered 5/5, 2013 at 13:29 Comment(3)
Sorry if I can only ask back quickly: Why don't you know if this is correct or not? Do you have got some error with it? Or do you expect something differently? And with your display problem: Are you aware that HTML has an image element?Gert
I have this in the body: foreach ($DOM->entry as $item ) { $image = (string) $item->image; $title = (string) $item->title; echo "<a href=''>$title</a>"; echo '<img src="$image" alt="$title" width="304" height="228">'; } but it only displays the title of the image it does not display the atual thumbnail itselfIzy
There is a bit more work to do and it's probably not that straight forward to understand, I left you an answer.Gert
G
0

After looking into the feed of your question, it shows that each item does not have an image element. Therefore accessing it will give you NULL which is echoed as an empty string (invisible):

foreach ($DOM->entry as $entry) {
    echo '<a href="">', htmlspecialchars($entry->title), '</a>', "\n",
         '<img src="', $entry->image, '" alt="', htmlspecialchars($entry->title), '" ',
              'width="304" height="228">', "\n";
    ;
}

The exemplary output shows that the title is available, but the image src is empty:

<a href="">Picadas, Marco Juarez  01-05-13</a>
<img src="" alt="Picadas, Marco Juarez  01-05-13" width="304" height="228">

Looking closer into the feed itself it turns out that there is not even any other element containing the thumbnail but the HTML text inside the conent element. And only inside that HTML there are the dimensions of the thumbnail image:

<entry>
    <title>Picadas, Marco Juarez  01-05-13</title>
    <link rel="alternate" type="text/html" href="http://www.flickr.com/photos/osvaldorainero/8709806523/"/>
    <id>tag:flickr.com,2005:/photo/8709806523</id>
    <published>2013-05-05T15:25:15Z</published>
    <updated>2013-05-05T15:25:15Z</updated>
    <flickr:date_taken>2013-05-01T15:42:01-08:00</flickr:date_taken>
    <dc:date.Taken>2013-05-01T15:42:01-08:00</dc:date.Taken>
    <content type="html">           &lt;p&gt;&lt;a href="http://www.flickr.com/people/osvaldorainero/"&gt;Osvaldo Rainero&lt;/a&gt; posted a photo:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez  01-05-13"&gt;&lt;img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez  01-05-13" /&gt;&lt;/a&gt;&lt;/p&gt;

</content>
    <author>
      <name>Osvaldo Rainero</name>
      <uri>http://www.flickr.com/people/osvaldorainero/</uri>
      <flickr:nsid>91267729@N05</flickr:nsid>
      <flickr:buddyicon>http://farm9.staticflickr.com/8107/buddyicons/[email protected]?1363607055#91267729@N05</flickr:buddyicon>
    </author>
    <link rel="enclosure" type="image/jpeg" href="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_b.jpg"/>
    <category term="cars" scheme="http://www.flickr.com/photos/tags/"/>
    ...
    <category term="arrancadas" scheme="http://www.flickr.com/photos/tags/"/>
</entry>

Zoom:

<content type="html">           &lt;p&gt;&lt;a href="http://www.flickr.com/people/osvaldorainero/"&gt;Osvaldo Rainero&lt;/a&gt; posted a photo:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez  01-05-13"&gt;&lt;img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez  01-05-13" /&gt;&lt;/a&gt;&lt;/p&gt;

</content>

This is HTML encoded in XML. And this is kind of a show-stopper for simplexml you use, because it can only return the HTML verbatim out of the box:

echo $entry->content, "\n";

Output (plain text):

<p><a href="http://www.flickr.com/people/osvaldorainero/">Osvaldo Rainero</a> posted a photo:</p>

<p><a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez  01-05-13"><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez  01-05-13" /></a></p>

This is the important part to understand: You do not only want to parse the XML from the feed, but you additionally want to parse HTML inside the node-value of an XML element.

So you need to extend the SimplexmlElement you use with a HTML parser. That is easy to do because if your PHP version ships with simplexml, it also ships with DOMDocument which has an HTML parser and it can return the parsed result as simplexml so this is pretty compatible.

So the following extends simplexml with a HTML parser:

class HtmledSimpleXML extends SimpleXMLElement
{
    /**
     * Parses element content as HTML and returns the
     * body element of it.
     *
     * @param string $xpath (optional) specify a different element to return
     *
     * @return SimpleXMLElement
     */
    public function html($xpath = '//body') {
        $doc = new DOMDocument();
        $doc->loadHTML($this);
        $xml = simplexml_import_dom($doc->documentElement);
        list($body) = $xml->xpath($xpath);
        return $body;
    }
}

It already allows to pass an xpath query to specify the concrete element you want to retrieve, normally that is the body tag from inside the HTML this is why it is set as default. Even if your HTML does not have that tag in there, it actually exists in the DOM, therefore this default is never wrong. But anyway in your case you're interested in the img tag. Thanks to simpelxml we can even output it directly as XML and can spare to even create the HTML by hand.

Usage example:

$DOM = new HtmledSimpleXML($body);

foreach ($DOM->entry as $entry) {
    echo '<a href="">', $entry->title, '</a>', "\n",
         $entry->content->html('//img')->asXML(), "\n";
    ;
}

The exemplary output for a single entry then is:

<a href="">Picadas, Marco Juarez  01-05-13</a>
<img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez  01-05-13"/>

Which should come pretty close to what you're looking for. Naturally you can as well just aquire the image-element and access it's attributes like with any other Simplexmlelement:

$thumb = $entry->content->html('//img');
echo 'Title: ', $entry->title, "\n",
     'Thumb: ', $thumb['src'], "\n",
     'Size : ', $thumb['width'], ' x ', $thumb['height'], "\n";

Output (plain text):

Title: Picadas, Marco Juarez  01-05-13
Thumb: http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg
Size : 240 x 161

I hope this is helpful so far.

Last time I extended SimpleXMLElement on Stackoverflow was to show how to parse CSV data inside the underlying XML structure in PHP simplexml xpath search for value in an ELEMENT containing tab delimited text?.

Gert answered 5/5, 2013 at 16:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.