1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13: class Ansel_Storage
14: {
15: 16: 17: 18: 19:
20: private $_db;
21:
22: 23: 24: 25: 26:
27: private $_shares;
28:
29: 30: 31: 32: 33:
34: private $_images = array();
35:
36: 37: 38: 39: 40: 41: 42:
43: public function __construct(Horde_Core_Share_Driver $shareOb)
44: {
45: $this->_shares = $shareOb;
46: }
47:
48: 49: 50: 51: 52:
53: public function __get($property)
54: {
55: switch ($property) {
56: case 'shares':
57: return $this->{'_' . $property};
58: default:
59: return null;
60: }
61: }
62:
63: 64: 65: 66: 67:
68: public function setStorage($storage)
69: {
70: $this->_db = $storage;
71: }
72:
73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83:
84: public function createGallery(array $attributes = array(),
85: Horde_Perms_Permission $perm = null,
86: $parent = null)
87: {
88:
89: if (empty($attributes['owner'])) {
90: $attributes['owner'] = $GLOBALS['registry']->getAuth();
91: }
92: if (empty($attributes['name'])) {
93: $attributes['name'] = _("Unnamed");
94: }
95: if (empty($attributes['desc'])) {
96: $attributes['desc'] = '';
97: }
98:
99:
100: $attributes['default_type'] = isset($attributes['default_type']) ?
101: $attributes['default_type'] :
102: 'auto';
103: $attributes['default'] = isset($attributes['default']) ?
104: (int)$attributes['default'] :
105: 0;
106: $attributes['default_prettythumb'] = isset($attributes['default_prettythumb']) ?
107: $attributes['default_prettythumb'] :
108: '';
109:
110:
111:
112: $attributes['style'] = isset($attributes['style']) ? $attributes['style'] : '';
113: $attributes['date_created'] = time();
114: $attributes['last_modified'] = $attributes['date_created'];
115: $attributes['images'] = isset($attributes['images']) ?
116: (int)$attributes['images'] :
117: 0;
118: $attributes['slug'] = isset($attributes['slug']) ? $attributes['slug'] : '';
119: $attributes['age'] = isset($attributes['age']) ? (int)$attributes['age'] : 0;
120: $attributes['download'] = isset($attributes['download']) ?
121: $attributes['download'] :
122: $GLOBALS['prefs']->getValue('default_download');
123: $attributes['view_mode'] = isset($attributes['view_mode']) ?
124: $attributes['view_mode'] :
125: 'Normal';
126: $attributes['passwd'] = isset($attributes['passwd']) ?
127: $attributes['passwd'] :
128: '';
129:
130:
131: if (isset($attributes['tags'])) {
132: $tags = $attributes['tags'];
133: unset($attributes['tags']);
134: } else {
135: $tags = array();
136: }
137:
138:
139: if (!empty($attributes['slug']) &&
140: $this->galleryExists(null, $attributes['slug'])) {
141: throw new Horde_Exception(
142: sprintf(_("The slug \"%s\" already exists."), $attributes['slug']));
143: }
144:
145:
146: try {
147: $gallery_share = $this->_shares->newShare(
148: $GLOBALS['registry']->getAuth(),
149: strval(new Horde_Support_Randomid()),
150: $attributes['name']);
151: } catch (Horde_Share_Exception $e) {
152: Horde::logMessage($e->getMessage, 'ERR');
153: throw new Ansel_Exception($e);
154: }
155: $gallery = $this->buildGallery($gallery_share);
156:
157:
158: if (!is_null($parent)) {
159: $gallery->setParent($parent);
160: if ($GLOBALS['conf']['ansel_cache']['usecache']) {
161: $GLOBALS['injector']->getInstance('Horde_Cache')
162: ->expire('Ansel_Gallery' . $parent);
163: }
164: }
165:
166:
167: foreach ($attributes as $key => $value) {
168: if ($key != 'name') {
169: $gallery->set($key, $value);
170: }
171: }
172:
173:
174: try {
175: $result = $this->_shares->addShare($gallery_share);
176: } catch (Horde_Share_Exception $e) {
177: $error = sprintf(_("The gallery \"%s\" could not be created: %s"),
178: $attributes['name'], $e->getMessage());
179: Horde::logMessage($error, 'ERR');
180: throw new Ansel_Exception($error);
181: }
182:
183:
184: if (empty($perm)) {
185: $perm = $gallery->getPermission();
186:
187:
188: switch ($GLOBALS['prefs']->getValue('default_permissions')) {
189: case 'read':
190: $perms = Horde_Perms::SHOW | Horde_Perms::READ;
191: break;
192: case 'edit':
193: $perms = Horde_Perms::SHOW | Horde_Perms::READ | Horde_Perms::EDIT;
194: break;
195: case 'none':
196: $perms = 0;
197: break;
198: }
199: $perm->addDefaultPermission($perms, false);
200:
201:
202: switch ($GLOBALS['prefs']->getValue('guest_permissions')) {
203: case 'read':
204: $perms = Horde_Perms::SHOW | Horde_Perms::READ;
205: break;
206: case 'none':
207: default:
208: $perms = 0;
209: break;
210: }
211: $perm->addGuestPermission($perms, false);
212:
213:
214: switch ($GLOBALS['prefs']->getValue('group_permissions')) {
215: case 'read':
216: $perms = Horde_Perms::SHOW | Horde_Perms::READ;
217: break;
218: case 'edit':
219: $perms = Horde_Perms::SHOW | Horde_Perms::READ | Horde_Perms::EDIT;
220: break;
221: case 'delete':
222: $perms = Horde_Perms::SHOW | Horde_Perms::READ | Horde_Perms::EDIT | Horde_Perms::DELETE;
223: break;
224: case 'none':
225: default:
226: $perms = 0;
227: break;
228: }
229:
230: if ($perms) {
231: $group_list = $GLOBALS['injector']
232: ->getInstance('Horde_Group')
233: ->listGroups($GLOBALS['registry']->getAuth());
234: if (count($group_list)) {
235: foreach ($group_list as $group_id => $group_name) {
236: $perm->addGroupPermission($group_id, $perms, false);
237: }
238: }
239: }
240: }
241: $gallery->setPermission($perm);
242:
243:
244: if (count($tags)) {
245: $gallery->setTags($tags);
246: }
247:
248: return $gallery;
249: }
250:
251: 252: 253: 254: 255: 256: 257: 258: 259: 260:
261: public function getGalleryBySlug($slug, array $overrides = array())
262: {
263: $shares = $this->buildGalleries(
264: $this->_shares->listShares(
265: $GLOBALS['registry']->getAuth(),
266: array('attributes' => array('slug' => $slug))));
267: if (!count($shares)) {
268: throw new Horde_Exception_NotFound(sprintf(_("Gallery %s not found."), $slug));
269: }
270:
271: return current($shares);
272: }
273:
274: 275: 276: 277: 278: 279: 280: 281: 282: 283:
284: public function getGallery($gallery_id, array $overrides = array())
285: {
286: if (!count($overrides) && $GLOBALS['conf']['ansel_cache']['usecache'] &&
287: ($gallery = $GLOBALS['injector']->getInstance('Horde_Cache')->get('Ansel_Gallery' . $gallery_id, $GLOBALS['conf']['cache']['default_lifetime'])) !== false) {
288:
289: if ($cached_gallery = unserialize($gallery)) {
290: return $cached_gallery;
291: }
292: }
293:
294: try {
295: $result = $this->buildGallery(
296: $this->_shares->getShareById($gallery_id)
297: );
298: } catch (Horde_Share_Exception $e) {
299: throw new Ansel_Exception($e);
300: }
301:
302: if (!count($overrides)) {
303: if ($GLOBALS['conf']['ansel_cache']['usecache']) {
304: $GLOBALS['injector']->getInstance('Horde_Cache')
305: ->set('Ansel_Gallery' . $gallery_id, serialize($result));
306: }
307: } else {
308: foreach ($overrides as $key => $value) {
309: $result->set($key, $value, false);
310: }
311: }
312:
313: return $result;
314: }
315:
316: 317: 318: 319: 320: 321: 322: 323:
324: public function getGalleriesBySlugs(array $slugs, $perms = Horde_Perms::SHOW)
325: {
326: try {
327: return $this->buildGalleries(
328: $this->_shares->listShares(
329: $GLOBALS['registry']->getAuth(),
330: array(
331: 'perm' => $perms,
332: 'attribtues' => array('slugs' => $slugs))));
333: } catch (Horde_Share_Exception $e) {
334: throw new Ansel_Exception($e);
335: }
336: }
337:
338: 339: 340: 341: 342: 343: 344: 345: 346:
347: public function getGalleries(array $ids, $perms = Horde_Perms::SHOW)
348: {
349: try {
350: $shares = $this->buildGalleries(
351: $this->_shares->getShares($ids));
352: } catch (Horde_Share_Exception $e) {
353: throw new Ansel_Exception($e);
354: }
355: $galleries = array();
356: foreach ($shares as $gallery) {
357: if ($gallery->hasPermission($GLOBALS['registry']->getAuth(), $perms)) {
358: $galleries[] = $gallery;
359: }
360: }
361:
362: return $galleries;
363: }
364:
365: 366: 367: 368: 369: 370: 371:
372: public function emptyGallery(Ansel_Gallery $gallery)
373: {
374: $gallery->clearStacks();
375: $images = $gallery->listImages();
376: foreach ($images as $image) {
377:
378:
379:
380: try {
381: $gallery->removeImage($image, true);
382: } catch (Horde_Exception_NotFound $e) {
383: throw new Ansel_Exception($e);
384: }
385: }
386: $gallery->set('images', 0, true);
387:
388:
389: if ($GLOBALS['conf']['ansel_cache']['usecache']) {
390: $GLOBALS['injector']
391: ->getInstance('Horde_Cache')
392: ->expire('Ansel_OtherGalleries' . $gallery->get('owner'));
393: $GLOBALS['injector']
394: ->getInstance('Horde_Cache')
395: ->expire('Ansel_Gallery' . $gallery->id);
396: }
397: }
398:
399: 400: 401: 402: 403: 404: 405:
406: public function removeGallery(Ansel_Gallery $gallery)
407: {
408:
409: $children = $gallery->getChildren(null, null, true);
410: foreach ($children as $child) {
411: $this->emptyGallery($child);
412: $child->setTags(array());
413: }
414:
415:
416: $this->emptyGallery($gallery);
417:
418:
419: $gallery->setTags(array());
420:
421:
422: $parent = $gallery->getParent();
423: $id = $gallery->id;
424:
425:
426: try {
427: $this->_shares->removeShare($gallery->getShare());
428: } catch (Horde_Share_Exception $e) {
429: throw new Ansel_Exception($e);
430: }
431:
432:
433: if ($GLOBALS['conf']['ansel_cache']['usecache']) {
434: $GLOBALS['injector']->getInstance('Horde_Cache')
435: ->expire('Ansel_Gallery' . $id);
436: }
437:
438:
439: if ($parent instanceof Ansel_Gallery) {
440: if (!$parent->countChildren($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW, false)) {
441: $parent->set('has_subgalleries', 0, true);
442: if ($GLOBALS['conf']['ansel_cache']['usecache']) {
443: $GLOBALS['injector']
444: ->getInstance('Horde_Cache')
445: ->expire('Ansel_Gallery' . $parent->id);
446: }
447: }
448: }
449: }
450:
451: 452: 453: 454: 455: 456: 457: 458:
459: public function &getImage($id)
460: {
461: if (isset($this->_images[$id])) {
462: return $this->_images[$id];
463: }
464:
465: $q = 'SELECT ' . $this->_getImageFields()
466: . ' FROM ansel_images WHERE image_id = ?';
467: try {
468: $image = $this->_db->selectOne($q, array((int)$id));
469: } catch (Horde_Db_Exception $e) {
470: throw new Ansel_Exception($e);
471: }
472:
473: if (!$image) {
474: throw new Horde_Exception_NotFound(_("Photo not found"));
475: } else {
476: $image['image_filename'] = Horde_String::convertCharset(
477: $image['image_filename'],
478: $GLOBALS['conf']['sql']['charset'],
479: 'UTF-8');
480: $image['image_caption'] = Horde_String::convertCharset(
481: $image['image_caption'],
482: $GLOBALS['conf']['sql']['charset'],
483: 'UTF-8');
484: $this->_images[$id] = new Ansel_Image($image);
485:
486: return $this->_images[$id];
487: }
488: }
489:
490: 491: 492: 493: 494: 495: 496: 497:
498: public function saveImage(Ansel_Image $image)
499: {
500:
501: if ($image->id) {
502: $update = 'UPDATE ansel_images SET image_filename = ?, '
503: . 'image_type = ?, image_caption = ?, image_sort = ?, '
504: . 'image_original_date = ?, image_latitude = ?, '
505: . 'image_longitude = ?, image_location = ?, '
506: . 'image_geotag_date = ? WHERE image_id = ?';
507: try {
508: return $this->_db->update(
509: $update,
510: array(Horde_String::convertCharset($image->filename, 'UTF-8', $GLOBALS['conf']['sql']['charset']),
511: $image->type,
512: Horde_String::convertCharset($image->caption, 'UTF-8', $GLOBALS['conf']['sql']['charset']),
513: $image->sort,
514: $image->originalDate,
515: $image->lat,
516: $image->lng,
517: $image->location,
518: $image->geotag_timestamp,
519: $image->id));
520: } catch (Horde_Db_Exception $e) {
521: throw new Ansel_Exception($e);
522: }
523: }
524:
525:
526: if (!$image->gallery || !strlen($image->filename) || !$image->type) {
527: throw new Ansel_Exception('Incomplete photo');
528: }
529:
530:
531: $insert = 'INSERT INTO ansel_images (gallery_id, image_filename, '
532: . 'image_type, image_caption, image_uploaded_date, image_sort, '
533: . 'image_original_date, image_latitude, image_longitude, '
534: . 'image_location, image_geotag_date) VALUES '
535: . '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
536:
537: try {
538: $image->id = $this->_db->insert(
539: $insert,
540: array($image->gallery,
541: Horde_String::convertCharset(
542: $image->filename,
543: 'UTF-8',
544: $GLOBALS['conf']['sql']['charset']),
545: $image->type,
546: Horde_String::convertCharset(
547: $image->caption,
548: 'UTF-8',
549: $GLOBALS['conf']['sql']['charset']),
550: $image->uploaded,
551: $image->sort,
552: $image->originalDate,
553: $image->lat,
554: $image->lng,
555: $image->location,
556: (empty($image->lat) ? 0 : $image->uploaded)));
557: } catch (Horde_Db_Exception $e) {
558: throw new Ansel_Exception($e);
559: }
560:
561: return $image->id;
562: }
563:
564: 565: 566: 567: 568: 569: 570: 571: 572:
573: public function saveImageAttribute($image_id, $attribute, $value)
574: {
575: try {
576: $this->_db->insert(
577: 'INSERT INTO ansel_image_attributes '
578: . '(image_id, attr_name, attr_value) VALUES (?, ?, ?)',
579: array(
580: $image_id,
581: $attribute,
582: Horde_String::convertCharset($value, 'UTF-8', $GLOBALS['conf']['sql']['charset'])));
583: } catch (Horde_Db_Exception $e) {
584: throw new Ansel_Exception($e);
585: }
586: }
587:
588: 589: 590: 591: 592: 593: 594:
595: public function clearImageAttributes($image_id)
596: {
597: try {
598: $this->_db->delete('DELETE FROM ansel_image_attributes WHERE image_id = ' . (int)$image_id);
599: } catch (Horde_Db_Exception $e) {
600: throw new Ansel_Exception($e);
601: }
602: }
603:
604: 605: 606: 607: 608: 609: 610: 611:
612: public function getImageAttributes($image_id)
613: {
614: try {
615: return $this->_db->selectAssoc(
616: 'SELECT attr_name, attr_value FROM ansel_image_attributes WHERE '
617: . ' image_id = ' . (int)$image_id);
618: } catch (Horde_Db_Exception $e) {
619: throw new Ansel_Exception($e);
620: }
621:
622: return $results;
623: }
624:
625: 626: 627: 628: 629: 630: 631: 632:
633: public function setImageSortOrder($imageId, $pos)
634: {
635: try {
636: $this->_db->update(
637: 'UPDATE ansel_images SET image_sort = '
638: . (int)$pos . ' WHERE image_id = ' . (int)$imageId);
639: } catch (Horde_Db_Exception $e) {
640: Horde::logMessage($e->getMessage(), 'ERR');
641: throw new Horde_Exception($e);
642: }
643: }
644:
645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659:
660: public function getImages(array $params = array())
661: {
662:
663: if (!empty($params['gallery_id'])) {
664: $sql = 'SELECT ' . $this->_getImageFields()
665: . ' FROM ansel_images WHERE gallery_id = '
666: . $params['gallery_id'] . ' ORDER BY image_sort';
667: } elseif (!empty($params['ids']) && is_array($params['ids']) && count($params['ids']) > 0) {
668: $sql = 'SELECT ' . $this->_getImageFields() . ' FROM ansel_images WHERE image_id IN (';
669: $i = 1;
670: $cnt = count($params['ids']);
671: foreach ($params['ids'] as $id) {
672: $sql .= (int)$id . (($i++ < $cnt) ? ',' : ');');
673: }
674: } else {
675: throw new InvalidArgumentException('Ansel_Storage::getImages requires either a gallery_id or an array of image ids');
676: }
677:
678:
679: if (isset($params['count']) && isset($params['from'])) {
680: $sql = $this->_db->addLimitOffset($sql, array('limit' => $params['count'], 'offset' => $params['from']));
681: }
682: try {
683: $images = $this->_db->select($sql);
684: } catch (Horde_Db_Exception $e) {
685: throw new Ansel_Exception($images);
686: }
687:
688: if (empty($images) && empty($params['gallery_id'])) {
689: throw new Horde_Exception_NotFound(_("Images not found"));
690: } elseif (empty($images)) {
691: return array();
692: }
693:
694: $return = array();
695: foreach ($images as $image) {
696: $image['image_filename'] = Horde_String::convertCharset($image['image_filename'], $GLOBALS['conf']['sql']['charset'], 'UTF-8');
697: $image['image_caption'] = Horde_String::convertCharset($image['image_caption'], $GLOBALS['conf']['sql']['charset'], 'UTF-8');
698: $return[$image['image_id']] = new Ansel_Image($image);
699: $this->_images[(int)$image['image_id']] = &$return[$image['image_id']];
700: }
701:
702:
703: $ccounts = $this->_getImageCommentCounts(array_keys($return));
704: if (count($ccounts)) {
705: foreach ($return as $key => $image) {
706: $return[$key]->commentCount = (!empty($ccounts[$key]) ? $ccounts[$key] : 0);
707: }
708: }
709:
710:
711: if (empty($params['gallery_id']) && !empty($params['preserve'])) {
712: foreach ($params['ids'] as $id) {
713: $ordered[$id] = $return[$id];
714: }
715: return $ordered;
716: }
717:
718: return $return;
719: }
720:
721: 722: 723: 724: 725: 726: 727:
728: protected function (array $ids)
729: {
730: global $conf, $registry;
731:
732:
733: if (($conf['comments']['allow'] == 'all' || ($conf['comments']['allow'] == 'authenticated' && $GLOBALS['registry']->getAuth())) &&
734: $registry->hasMethod('forums/numMessagesBatch')) {
735:
736: return $registry->call('forums/numMessagesBatch', array($ids, 'ansel'));
737: }
738:
739: return array();
740: }
741:
742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755:
756: public function getRecentImages(array $galleries = array(), $limit = 10, array $slugs = array())
757: {
758: $results = array();
759:
760: if (!count($galleries) && !count($slugs)) {
761:
762:
763: foreach ($this->_shares->listShares($GLOBALS['registry']->getAuth()) as $share) {
764: $galleries[] = $share->getId();
765: }
766: if (empty($galleries)) {
767: return array();
768: }
769: }
770: if (!count($slugs)) {
771:
772: $sql = 'SELECT ' . $this->_getImageFields() . ' FROM ansel_images '
773: . 'WHERE gallery_id IN ('
774: . str_repeat('?, ', count($galleries) - 1) . '?) ';
775: $criteria = $galleries;
776: } elseif (count($slugs)) {
777:
778: $sql = 'SELECT ' . $this->_getImageFields() . ' FROM ansel_images LEFT JOIN '
779: . $this->_shares->getTable() . ' ON ansel_images.gallery_id = '
780: . $this->_shares->getTable() . '.share_id ' . 'WHERE attribute_slug IN ('
781: . str_repeat('?, ', count($slugs) - 1) . '?) ';
782: $criteria = $slugs;
783: }
784:
785: $sql .= ' ORDER BY image_uploaded_date DESC';
786: if ($limit > 0) {
787: $sql = $this->_db->addLimitOffset($sql, array('limit' => (int)$limit));
788: }
789: try {
790: $images = $this->_db->selectAll($sql, $criteria);
791: } catch (Horde_Db_Exception $e) {
792: throw new Ansel_Exception($e);
793: }
794:
795: foreach($images as $image) {
796: $image['image_filename'] = Horde_String::convertCharset($image['image_filename'], $GLOBALS['conf']['sql']['charset'], 'UTF-8');
797: $image['image_caption'] = Horde_String::convertCharset($image['image_caption'], $GLOBALS['conf']['sql']['charset'], 'UTF-8');
798: $results[] = new Ansel_Image($image);
799: }
800:
801: return $results;
802: }
803:
804: 805: 806: 807: 808: 809: 810: 811: 812: 813:
814: public function galleryExists($gallery_id = null, $slug = null)
815: {
816: if (empty($slug)) {
817: $results = $this->_shares->idExists($gallery_id);
818: } else {
819: $results = $this->_shares->countShares($GLOBALS['registry']->getAuth(), Horde_Perms::READ, array('slug' => $slug));
820: }
821:
822: return (bool)$results;
823: }
824:
825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846:
847: public function countGalleries($userid, array $params = array())
848: {
849: static $counts;
850:
851: $oparams = new Horde_Support_Array($params);
852: if ($oparams->parent) {
853: $parent_id = $oparams->parent->id;
854: } else {
855: $parent_id = null;
856: }
857: $perm = $oparams->get('perm', Horde_Perms::SHOW);
858: $key = "$userid,$perm,$parent_id,{$oparams->all_levels}" . serialize($oparams->get('attributes', array())) . serialize($oparams->get('tags', array()));
859: if (isset($counts[$key])) {
860: return $counts[$key];
861: }
862:
863:
864:
865: if ($oparams->tags) {
866: $count = count($this->listGalleries($params));
867: } else {
868: try {
869: $count = $this->_shares->countShares(
870: $userid,
871: $perm, $oparams->get('attributes', array()),
872: $parent_id,
873: $oparams->get('all_levels', true));
874: } catch (Horde_Share_Exception $e) {
875: throw new Ansel_Exception($e);
876: }
877: }
878: $counts[$key] = $count;
879:
880: return $count;
881: }
882:
883: 884: 885: 886: 887: 888: 889: 890: 891: 892: 893: 894: 895: 896: 897: 898: 899: 900: 901: 902: 903: 904:
905: public function listGalleries($params = array())
906: {
907: $galleries = array();
908: try {
909: if (!empty($params['tags'])) {
910: $count = !empty($params['count']) ? $params['count'] : null;
911: $from = !empty($params['from']) ? $params['from'] : null;
912: unset($params['count'], $params['from']);
913: $shares = $this->_shares->listShares($GLOBALS['registry']->getAuth(), $params);
914: if (!empty($params['attributes']) && !is_array($params['attributes'])) {
915: $user = $params['attributes'];
916: } elseif (!empty($params['attributes']['owner'])) {
917: $user = $params['attributes']['owner'];
918: } else {
919: $user = null;
920: }
921: $tagged = $GLOBALS['injector']
922: ->getInstance('Ansel_Tagger')
923: ->search(
924: $params['tags'],
925: array(
926: 'type' => 'gallery',
927: 'user' => $user));
928:
929: foreach ($shares as $share) {
930: if (in_array($share->getId(), $tagged['galleries'])) {
931: $galleries[] = $share;
932: }
933: }
934: $galleries = array_slice($galleries, $from, $count);
935: } else {
936: $galleries = $this->_shares->listShares($GLOBALS['registry']->getAuth(), $params);
937: }
938: $shares = $this->buildGalleries($galleries);
939: } catch (Horde_Share_Exception $e) {
940: throw new Ansel_Exception($e);
941: }
942:
943: return $shares;
944: }
945:
946: 947: 948: 949: 950:
951: public function listAllGalleries()
952: {
953: return $this->buildGalleries($this->_shares->listAllShares());
954: }
955:
956: 957: 958: 959: 960: 961: 962: 963: 964: 965: 966: 967: 968:
969: public function getImageJson(array $images, Ansel_Style $style = null,
970: $full = false, $image_view = 'mini', $view_links = false)
971: {
972: $galleries = array();
973: if (is_null($style)) {
974: $style = Ansel::getStyleDefinition('ansel_default');
975: }
976:
977: $json = array();
978:
979: foreach ($images as $id) {
980: $image = $this->getImage($id);
981: $gallery_id = abs($image->gallery);
982: if (empty($galleries[$gallery_id])) {
983: $galleries[$gallery_id]['gallery'] = $GLOBALS['injector']->getInstance('Ansel_Storage')->getGallery($gallery_id);
984: }
985:
986:
987:
988:
989: if (!isset($galleries[$gallery_id]['perm'])) {
990: $galleries[$gallery_id]['perm'] =
991: ($galleries[$gallery_id]['gallery']->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ) &&
992: $galleries[$gallery_id]['gallery']->isOldEnough() &&
993: !$galleries[$gallery_id]['gallery']->hasPasswd());
994: }
995:
996: if ($galleries[$gallery_id]['perm']) {
997: $data = array((string)Ansel::getImageUrl($image->id, $image_view, $full, $style),
998: htmlspecialchars($image->filename),
999: $GLOBALS['injector']->getInstance('Horde_Core_Factory_TextFilter')->filter($image->caption, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO_LINKURL)),
1000: $image->id,
1001: 0);
1002:
1003: if ($view_links) {
1004: $data[] = (string)Ansel::getUrlFor('view',
1005: array('gallery' => $image->gallery,
1006: 'image' => $image->id,
1007: 'view' => 'Image',
1008: 'slug' => $galleries[$gallery_id]['gallery']->get('slug')),
1009: $full);
1010:
1011: $data[] = (string)Ansel::getUrlFor('view',
1012: array('gallery' => $image->gallery,
1013: 'slug' => $galleries[$gallery_id]['gallery']->get('slug'),
1014: 'view' => 'Gallery'),
1015: $full);
1016: }
1017:
1018: $json[] = $data;
1019: }
1020:
1021: }
1022:
1023: return Horde_Serialize::serialize($json, Horde_Serialize::JSON);
1024: }
1025:
1026: 1027: 1028: 1029: 1030:
1031: public function getRandomGallery(array $params = array())
1032: {
1033: $galleries = $this->listGalleries($params);
1034: if (!$galleries) {
1035: return false;
1036: }
1037:
1038: return $galleries[array_rand($galleries)];
1039: }
1040:
1041: 1042: 1043: 1044: 1045: 1046: 1047: 1048: 1049: 1050: 1051: 1052: 1053: 1054: 1055: 1056: 1057: 1058: 1059: 1060: 1061:
1062: public function listImages(array $params = array())
1063: {
1064: $params = new Horde_Support_Array($params);
1065: if (is_array($params['fields'])) {
1066: $field_count = count($params['fields']);
1067: $params['fields'] = implode(', ', $params['fields']);
1068: } elseif ($params['fields'] == '*') {
1069:
1070: $field_count = 2;
1071: } else {
1072: $field_count = substr_count($params->get('fields', 'image_id'), ',') + 1;
1073: }
1074:
1075: if (is_array($params['sort'])) {
1076: $params['sort'] = implode(', ', $params['sort']);
1077: }
1078:
1079: if (is_array($params['gallery_id'])) {
1080: $query_where = 'WHERE gallery_id IN (' . implode(',', $params['gallery_id']) . ')';
1081: } elseif ($params['gallery_id']) {
1082: $query_where = 'WHERE gallery_id = ' . $params['gallery_id'];
1083: } else {
1084: $query_where = '';
1085: }
1086: if ($params['filter']) {
1087: foreach ($params['filter'] as $filter) {
1088: $query_where .= (!empty($query_where) ? ' AND ' : ' WHERE ')
1089: . $this->_toImageDriverName($filter['property'])
1090: . ' ' . $filter['op'] . ' ' .
1091: (is_array($filter['value']) ? '(' . implode(',', $filter['value']) . ')' : $filter['value']);
1092: }
1093: }
1094: $sql = 'SELECT ' . $params->get('fields', 'image_id')
1095: . ' FROM ansel_images ' . $query_where
1096: . ' ORDER BY ' . $params->get('sort', 'image_sort');
1097: $sql = $this->_db->addLimitOffset(
1098: $sql,
1099: array(
1100: 'limit' => $params->get('limit', 0),
1101: 'offset' => $params->get('offset', 0))
1102: );
1103: try {
1104: if ($field_count > 1) {
1105: $results = $this->_db->selectAll($sql);
1106: $images = array();
1107: foreach ($results as $image) {
1108: $images[$image['image_id']] = $image;
1109: }
1110: return $images;
1111: } else {
1112: return $this->_db->selectValues($sql);
1113: }
1114: } catch (Horde_Db_Exception $e) {
1115: throw new Ansel_Exception($e);
1116: }
1117: }
1118:
1119: 1120: 1121: 1122: 1123: 1124: 1125: 1126: 1127: 1128:
1129: public function getImagesGeodata(array $image_ids = array(), $gallery = null)
1130: {
1131: if ((!is_array($image_ids) || count($image_ids) == 0) && empty($gallery)) {
1132: return array();
1133: }
1134: $params = array(
1135: 'fields' => array(
1136: 'image_id as id',
1137: 'image_id',
1138: 'image_latitude',
1139: 'image_longitude',
1140: 'image_location'),
1141: 'filter' => array(
1142: array(
1143: 'property' => 'latitude',
1144: 'op' => '!=',
1145: 'value' => "''"))
1146: );
1147: if (!empty($gallery)) {
1148: $params['gallery_id'] = (int)$gallery;
1149: } elseif (count($image_ids) > 0) {
1150: $params['filter'][] = array(
1151: 'property' => 'id',
1152: 'op' => 'IN',
1153: 'value' => $image_ids);
1154: } else {
1155: return array();
1156: }
1157:
1158: return $this->listImages($params);
1159: }
1160:
1161: 1162: 1163: 1164: 1165: 1166: 1167: 1168: 1169: 1170: 1171: 1172:
1173: public function getRecentImagesGeodata($user = null, $start = 0, $count = 8)
1174: {
1175: $galleries = $this->listGalleries(
1176: array(
1177: 'perm' => Horde_Perms::EDIT,
1178: 'attributes' => $user
1179: )
1180: );
1181: $ids = array();
1182: foreach ($galleries as $gallery) {
1183: $ids[] = $gallery->id;
1184: }
1185: if (empty($ids)) {
1186: return array();
1187: }
1188:
1189: $params = array(
1190: 'offset' => $start,
1191: 'limit' => $count,
1192: 'fields' => array(
1193: 'image_id as id',
1194: 'image_id',
1195: 'gallery_id',
1196: 'image_latitude',
1197: 'image_longitude',
1198: 'image_location'),
1199: 'gallery_id' => $ids,
1200: 'filter' => array(
1201: array(
1202: 'property' => 'latitude',
1203: 'op' => '!=',
1204: 'value' => "''")
1205: ),
1206: 'sort' => 'image_geotag_date DESC');
1207:
1208: return $this->listImages($params);
1209: }
1210:
1211: 1212: 1213: 1214: 1215: 1216: 1217: 1218: 1219:
1220: public function searchLocations($search = '')
1221: {
1222: $sql = 'SELECT DISTINCT image_location, image_latitude, image_longitude FROM ansel_images WHERE LENGTH(image_location) > 0';
1223: if (strlen($search)) {
1224: $sql .= ' AND image_location LIKE ' . $this->_db->quoteString("$search%");
1225: }
1226: try {
1227: return $this->_db->selectAll($sql);
1228: } catch (Horde_Db_Exception $e) {
1229: throw new Ansel_Exception($e);
1230: }
1231: }
1232:
1233: 1234: 1235: 1236: 1237: 1238: 1239: 1240: 1241:
1242: public function setImagesGallery(array $image_ids, $gallery_id)
1243: {
1244: try {
1245: $this->_db->update('UPDATE ansel_images SET gallery_id = ' . $gallery_id . ' WHERE image_id IN (' . implode(',', $image_ids) . ')');
1246: } catch (Horde_Db_Exception $e) {
1247: Horde::logMessage($e->getMessage(), 'ERR');
1248: throw new Ansel_Exception($e);
1249: }
1250: }
1251:
1252: 1253: 1254: 1255: 1256: 1257: 1258:
1259: public function removeImage($image_id)
1260: { try {
1261: $this->_db->delete('DELETE FROM ansel_images WHERE image_id = ' . (int)$image_id);
1262: $this->_db->delete('DELETE FROM ansel_image_attributes WHERE image_id = ' . (int)$image_id);
1263: } catch (Horde_Db_Exception $e) {
1264: throw new Ansel_Exception($e);
1265: }
1266: }
1267:
1268: 1269: 1270: 1271: 1272:
1273: protected function _getImageFields($alias = '')
1274: {
1275: $fields = array(
1276: 'image_id', 'gallery_id', 'image_filename', 'image_type',
1277: 'image_caption', 'image_uploaded_date', 'image_sort',
1278: 'image_faces', 'image_original_date', 'image_latitude',
1279: 'image_longitude', 'image_location', 'image_geotag_date');
1280: if (!empty($alias)) {
1281: foreach ($fields as $field) {
1282: $new[] = $alias . '.' . $field;
1283: }
1284: return implode(', ', $new);
1285: }
1286:
1287: return implode(', ', $fields);
1288: }
1289:
1290: 1291: 1292: 1293: 1294:
1295: public function ensureHash($hash)
1296: {
1297: $query = 'SELECT COUNT(*) FROM ansel_hashes WHERE style_hash = ?';
1298: try {
1299: $results = $this->_db->selectValue($query, array($hash));
1300: } catch (Horde_Db_Exception $e) {
1301: throw new Ansel_Exception($e);
1302: }
1303: if (!$results) {
1304: try {
1305: $this->_db->insert('INSERT INTO ansel_hashes (style_hash) VALUES(?)', array($hash));
1306: } catch (Horde_Db_Exception $e) {
1307: throw new Ansel_Exception($e);
1308: }
1309: }
1310: }
1311:
1312: 1313: 1314: 1315: 1316:
1317: public function getHashes()
1318: {
1319: try {
1320: return $this->_db->selectValues('SELECT style_hash FROM ansel_hashes');
1321: } catch (Horde_Db_Exception $e) {
1322: throw new Ansel_Exception($e);
1323: }
1324: }
1325:
1326: 1327: 1328: 1329: 1330: 1331: 1332:
1333: public function buildGallery(Horde_Share_Object $share)
1334: {
1335: return current($this->buildGalleries(array($share)));
1336: }
1337:
1338: 1339: 1340: 1341: 1342: 1343: 1344: 1345:
1346: public function buildGalleries(array $shares)
1347: {
1348: $results = array();
1349: foreach ($shares as $share) {
1350: $results[] = new Ansel_Gallery($share);
1351: }
1352:
1353: return $results;
1354: }
1355:
1356: 1357: 1358: 1359: 1360: 1361: 1362:
1363: protected function _toImageDriverName($field)
1364: {
1365: switch ($field) {
1366: case 'id':
1367: case 'filename':
1368: case 'type':
1369: case 'caption':
1370: case 'sort':
1371: case 'faces':
1372: case 'latitude':
1373: case 'longitude':
1374: case 'location':
1375: return 'image_' . $field;
1376: case 'uploadedDate':
1377: return 'image_uploaded_date';
1378: case 'originalDate':
1379: return 'image_original_date';
1380: case 'geotagDate':
1381: return 'image_geotag_date';
1382: }
1383: }
1384:
1385: }
1386: