1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 use Joomla\Registry\Registry;
13
14 15 16 17 18 19
20 class JGoogleDataPicasaAlbum extends JGoogleData
21 {
22 23 24 25
26 protected $xml;
27
28 29 30 31 32 33 34 35 36
37 public function __construct(SimpleXMLElement $xml, Registry $options = null, JGoogleAuth $auth = null)
38 {
39 $this->xml = $xml;
40
41 parent::__construct($options, $auth);
42
43 if (isset($this->auth) && !$this->auth->getOption('scope'))
44 {
45 $this->auth->setOption('scope', 'https://picasaweb.google.com/data/');
46 }
47 }
48
49 50 51 52 53 54 55 56 57 58 59 60
61 public function delete($match = '*')
62 {
63 if ($this->isAuthenticated())
64 {
65 $url = $this->getLink();
66
67 if ($match === true)
68 {
69 $match = $this->xml->xpath('./@gd:etag');
70 $match = $match[0];
71 }
72
73 try
74 {
75 $jdata = $this->query($url, null, array('GData-Version' => 2, 'If-Match' => $match), 'delete');
76 }
77 catch (Exception $e)
78 {
79 if (strpos($e->getMessage(), 'Error code 412 received requesting data: Mismatch: etags') === 0)
80 {
81 throw new RuntimeException("Etag match failed: `$match`.", $e->getCode(), $e);
82 }
83
84 throw $e;
85 }
86
87 if ($jdata->body != '')
88 {
89 throw new UnexpectedValueException("Unexpected data received from Google: `{$jdata->body}`.");
90 }
91
92 $this->xml = null;
93
94 return true;
95 }
96 else
97 {
98 return false;
99 }
100 }
101
102 103 104 105 106 107 108 109 110
111 public function getLink($type = 'edit')
112 {
113 $links = $this->xml->link;
114
115 foreach ($links as $link)
116 {
117 if ($link->attributes()->rel == $type)
118 {
119 return (string) $link->attributes()->href;
120 }
121 }
122
123 return false;
124 }
125
126 127 128 129 130 131 132
133 public function getTitle()
134 {
135 return (string) $this->xml->children()->title;
136 }
137
138 139 140 141 142 143 144
145 public function getSummary()
146 {
147 return (string) $this->xml->children()->summary;
148 }
149
150 151 152 153 154 155 156
157 public function getLocation()
158 {
159 return (string) $this->xml->children('gphoto', true)->location;
160 }
161
162 163 164 165 166 167 168
169 public function getAccess()
170 {
171 return (string) $this->xml->children('gphoto', true)->access;
172 }
173
174 175 176 177 178 179 180
181 public function getTime()
182 {
183 return (double) $this->xml->children('gphoto', true)->timestamp / 1000;
184 }
185
186 187 188 189 190 191 192 193 194
195 public function setTitle($title)
196 {
197 $this->xml->children()->title = $title;
198
199 return $this;
200 }
201
202 203 204 205 206 207 208 209 210
211 public function setSummary($summary)
212 {
213 $this->xml->children()->summary = $summary;
214
215 return $this;
216 }
217
218 219 220 221 222 223 224 225 226
227 public function setLocation($location)
228 {
229 $this->xml->children('gphoto', true)->location = $location;
230
231 return $this;
232 }
233
234 235 236 237 238 239 240 241 242
243 public function setAccess($access)
244 {
245 $this->xml->children('gphoto', true)->access = $access;
246
247 return $this;
248 }
249
250 251 252 253 254 255 256 257 258
259 public function setTime($time)
260 {
261 $this->xml->children('gphoto', true)->timestamp = $time * 1000;
262
263 return $this;
264 }
265
266 267 268 269 270 271 272 273 274 275
276 public function save($match = '*')
277 {
278 if ($this->isAuthenticated())
279 {
280 $url = $this->getLink();
281
282 if ($match === true)
283 {
284 $match = $this->xml->xpath('./@gd:etag');
285 $match = $match[0];
286 }
287
288 try
289 {
290 $headers = array('GData-Version' => 2, 'Content-type' => 'application/atom+xml', 'If-Match' => $match);
291 $jdata = $this->query($url, $this->xml->asXml(), $headers, 'put');
292 }
293 catch (Exception $e)
294 {
295 if (strpos($e->getMessage(), 'Error code 412 received requesting data: Mismatch: etags') === 0)
296 {
297 throw new RuntimeException("Etag match failed: `$match`.", $e->getCode(), $e);
298 }
299
300 throw $e;
301 }
302
303 $this->xml = $this->safeXml($jdata->body);
304
305 return $this;
306 }
307 else
308 {
309 return false;
310 }
311 }
312
313 314 315 316 317 318 319 320
321 public function refresh()
322 {
323 if ($this->isAuthenticated())
324 {
325 $url = $this->getLink();
326 $jdata = $this->query($url, null, array('GData-Version' => 2));
327 $this->xml = $this->safeXml($jdata->body);
328
329 return $this;
330 }
331 else
332 {
333 return false;
334 }
335 }
336
337 338 339 340 341 342 343 344
345 public function listPhotos()
346 {
347 if ($this->isAuthenticated())
348 {
349 $url = $this->getLink('http://schemas.google.com/g/2005#feed');
350 $jdata = $this->query($url, null, array('GData-Version' => 2));
351 $xml = $this->safeXml($jdata->body);
352
353 if (isset($xml->children()->entry))
354 {
355 $items = array();
356
357 foreach ($xml->children()->entry as $item)
358 {
359 $items[] = new JGoogleDataPicasaPhoto($item, $this->options, $this->auth);
360 }
361
362 return $items;
363 }
364 else
365 {
366 throw new UnexpectedValueException("Unexpected data received from Google: `{$jdata->body}`.");
367 }
368 }
369 else
370 {
371 return false;
372 }
373 }
374
375 376 377 378 379 380 381 382 383 384 385 386
387 public function upload($file, $title = '', $summary = '')
388 {
389 if ($this->isAuthenticated())
390 {
391 jimport('joomla.filesystem.file');
392 $title = $title != '' ? $title : JFile::getName($file);
393
394 if (!($type = $this->getMime($file)))
395 {
396 throw new RuntimeException('Inappropriate file type.');
397 }
398
399 if (!($data = file_get_contents($file)))
400 {
401 throw new RuntimeException("Cannot access file: `$file`");
402 }
403
404 $xml = new SimpleXMLElement('<entry></entry>');
405 $xml->addAttribute('xmlns', 'http://www.w3.org/2005/Atom');
406 $xml->addChild('title', $title);
407 $xml->addChild('summary', $summary);
408 $cat = $xml->addChild('category', '');
409 $cat->addAttribute('scheme', 'http://schemas.google.com/g/2005#kind');
410 $cat->addAttribute('term', 'http://schemas.google.com/photos/2007#photo');
411
412 $post = "Media multipart posting\n";
413 $post .= "--END_OF_PART\n";
414 $post .= "Content-Type: application/atom+xml\n\n";
415 $post .= $xml->asXml() . "\n";
416 $post .= "--END_OF_PART\n";
417 $post .= "Content-Type: {$type}\n\n";
418 $post .= $data;
419
420 $jdata = $this->query($this->getLink(), $post, array('GData-Version' => 2, 'Content-Type: multipart/related'), 'post');
421
422 return new JGoogleDataPicasaPhoto($this->safeXml($jdata->body), $this->options, $this->auth);
423 }
424 else
425 {
426 return false;
427 }
428 }
429
430 431 432 433 434 435 436 437 438 439
440 protected function getMime($file)
441 {
442 switch (strtolower(JFile::getExt($file)))
443 {
444 case 'bmp':
445 case 'bm':
446 return 'image/bmp';
447 case 'gif':
448 return 'image/gif';
449 case 'jpg':
450 case 'jpeg':
451 case 'jpe':
452 case 'jif':
453 case 'jfif':
454 case 'jfi':
455 return 'image/jpeg';
456 case 'png':
457 return 'image/png';
458 case '3gp':
459 return 'video/3gpp';
460 case 'avi':
461 return 'video/avi';
462 case 'mov':
463 case 'moov':
464 case 'qt':
465 return 'video/quicktime';
466 case 'mp4':
467 case 'm4a':
468 case 'm4p':
469 case 'm4b':
470 case 'm4r':
471 case 'm4v':
472 return 'video/mp4';
473 case 'mpg':
474 case 'mpeg':
475 case 'mp1':
476 case 'mp2':
477 case 'mp3':
478 case 'm1v':
479 case 'm1a':
480 case 'm2a':
481 case 'mpa':
482 case 'mpv':
483 return 'video/mpeg';
484 case 'asf':
485 return 'video/x-ms-asf';
486 case 'wmv':
487 return 'video/x-ms-wmv';
488 default:
489 return false;
490 }
491 }
492 }
493