2 /* vim: set expandtab shiftwidth=4 softtabstop=4 tabstop=4 foldmethod=marker: */
5 * TIP_Picasa2 photo access
7 * LICENSE: This source file is subject to the New BSD license that is
8 * available through the world-wide-web at the following URI:
9 * http://www.opensource.org/licenses/bsd-license.php
10 * If you did not receive a copy of the New BSD License and are unable to
11 * obtain it through the web, please send a note to license@php.net so we
12 * can mail you a copy immediately.
14 * @author Nicola Fontana <ntd@entidi.it>
15 * @copyright Copyright © 2010 Nicola Fontana
16 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
22 * A content module to access picasa version 2 photo throught its album feed
24 * A TIP_Content implementation that sets a default data engine
25 * capable to directly parse picasa album feed (version 2) to get
28 * To be able to use this module, you should configure a picasa2
29 * module in your configuration options and feed it with the URI
30 * of the feed of a picasa album:
36 * 'type' => array('module', 'content', 'picasa2'),
37 * 'data' => 'http://picasaweb.google.com/data/feed/base/user/.../albumid/...'
43 * The TIP_Picasa2 access to the feed is read-only but you need
44 * to fulfill the PicasaWeb Terms of Service in order to be allowed
47 * http://code.google.com/apis/picasaweb/terms.html
49 * After configuring it, you can use your newly "picture" module in
50 * the same way a common TIP_Content module is used.
52 * To be able to access the feed, TIP_Picasa2 considers any
53 * <entry> in the feed as any SQL engine treats a row in a table.
54 * The field of this virtual row are mapped to a usable field id
55 * using the "fields_xpath" property of the TIP_XML engine. Here
56 * it is a (probably outdated) list of these virtual fields
57 * (together with the XPath used to map their value):
59 * - **id** ({{link[contains(@rel,"#canonical")]/@href}})
60 * - **title** ({{media:group/media:title[@type="plain"]}})
61 * - **description** ({{media:group/media:description[@type="plain"]}})
62 * - **imageurl** ({{media:group/media:content[@medium="image"]/@url}})
63 * - **thumbnail** ({{media:group/media:thumbnail[3]/@url}})
64 * - **thumbnail_width** ({{media:group/media:thumbnail[3]/@width}})
65 * - **thumbnail_height** ({{media:group/media:thumbnail[3]/@height}})
66 * - **date** ({{published}})
67 * - **author** ({{../author/name}})
68 * - **uploader** ({{media:group/media:credit}})
70 * Adding new field mapping is trivial: up to now it was added what
73 * The above fields can be used in you templates just as every other
74 * field provided by the more usual TIP_Mysql engine. For instance,
75 * to get a list of the first 5 items, you can do something like this:
78 * <ul class="picture">{picture.forSelect(LIMIT 5)}
79 * <li><a href="{imageurl}">
80 * <img src="{thumbnail}" width="{thumbnail_width}" height="{thumbnail_height}" alt="{description}" />
85 * Because TIP_Picasa2 accesses the underlying feed using the TIP_XML
86 * data engine there are some known restriction: for instance,
87 * you can't do a complex SQL query using the ORDER BY or GROUP BY
88 * clauses. Check the TIP_XML documentation to exactly know which
89 * queries can be executed.
93 class TIP_Picasa2
extends TIP_Content
95 //{{{ Construction/destruction
97 static protected function checkOptions(&$options)
99 if (@is_string
($options['data'])) {
100 $options['data'] = array('path' => $options['data']);
103 // The data path is a required option
104 if (!@is_array
($options['data']) ||
!isset($options['data']['path'])) {
108 TIP
::arrayDefault($options, 'id_type', 'string');
109 TIP
::arrayDefault($options['data'], 'data_engine', array(
111 'type' => array('data_engine', 'xml'),
112 'fields_xpath' => array(
113 'id' => 'link[contains(@rel,"#canonical")]/@href',
114 'title' => 'media:group/media:title[@type="plain"]',
115 'description' => 'media:group/media:description[@type="plain"]',
116 'imageurl' => 'media:group/media:content[@medium="image"]/@url',
117 'thumbnail' => 'media:group/media:thumbnail[3]/@url',
118 'thumbnail_width' => 'media:group/media:thumbnail[3]/@width',
119 'thumbnail_height' => 'media:group/media:thumbnail[3]/@height',
120 'date' => 'published',
121 'author' => '../author/name',
122 'uploader' => 'media:group/media:credit'
125 return parent
::checkOptions($options);
131 * Initializes a TIP_Picasa2 instance.
133 * @param array $options Properties values
135 protected function __construct($options)
137 parent
::__construct($options);
144 * Get the html code for a PicasaWeb picture
146 * Renders the provided PicasaWeb URI (in the canonical form,
147 * usually something like http://picasaweb.google.com/lh/photo/...)
148 * to the proper <a ...><img ... /></a> element.
150 * This method starts (and ends) a view to find the row, so any
151 * further request is cached.
153 * @param string $id The PicasaWeb URI of the photo
154 * @return string|false The string to render or false on errors
156 public function toHtml($id)
158 if (is_null($view =& $this->startDataView($this->getData()->rowFilter($id)))) {
159 TIP
::notifyError('select');
163 $rows =& $view->getProperty('rows');
164 if (!@array_key_exists
($id, $rows))
167 return self
::_renderRow($rows[$id], array('class' => 'picasa2'));
171 * Get the html code for the whole PicasaWeb album
173 * Renders all the photo included by this album.
175 * @return string|false The string to render or false on errors
177 public function toHtmlAlbum()
181 if (is_null($view =& $this->startDataView())) {
182 TIP
::notifyError('select');
186 $rows =& $view->getProperty('rows');
191 'max-width' => &$max_width,
192 'max-height' => &$max_height
195 foreach ($rows as $row) {
196 $output .= ' <li>' . self
::_renderRow($row, $options) . '</li>';
202 $id = 'Album' . $cnt;
206 <div class="caption" style="float: right">
210 <p class="caption-title"><a id="$id-prev" href="#">« PRECEDENTE</a> <a id="$id-next" href="#">SEGUENTE »</a></p>
212 <script type="text/javascript">
214 jQuery('#$id').ulslide({
228 static private function _renderRow($row, $options = null)
230 $id = TIP
::toHtml($row['id']);
231 $description = TIP
::toHtml($row['description']);
232 $src = TIP
::toHtml($row['thumbnail']);
233 $width = (int) $row['thumbnail_width'];
234 $height = (int) $row['thumbnail_height'];
236 $attrs = 'href="' . $id . '"';
237 empty($description) ||
$attrs .= ' title="' . $description . '"';
238 isset($options['class']) && $attrs .= ' class="' . $options['class'] . '"';
240 if (isset($options['max-width']) && $width > $options['max-width'])
241 $options['max-width'] = $width;
242 if (isset($options['max-height']) && $height > $options['max-height'])
243 $options['max-height'] = $height;
245 return "<a $attrs><img src=\"$src\" width=\"$width\" height=\"$height\" alt=\"$description\" /></a>\n";