1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Ansel_GalleryMode_Date extends Ansel_GalleryMode_Base
15: {
16: 17: 18: 19: 20:
21: protected $_date = array();
22:
23: 24: 25: 26: 27:
28: protected $_features = array('slideshow', 'zipdownload', 'upload');
29:
30: 31: 32: 33: 34:
35: protected $_subGalleries = null;
36:
37: 38: 39: 40: 41: 42: 43:
44: public function hasFeature($feature)
45: {
46:
47: switch ($feature) {
48: case 'sort_images':
49: case 'image_captions':
50: case 'faces':
51:
52: return !empty($this->_date['day']);
53:
54: default:
55: return parent::hasFeature($feature);
56: }
57: }
58:
59: 60: 61: 62: 63: 64:
65: public function getGalleryCrumbData()
66: {
67: $year = !empty($this->_date['year']) ? $this->_date['year'] : 0;
68: $month = !empty($this->_date['month']) ? $this->_date['month'] : 0;
69: $day = !empty($this->_date['day']) ? $this->_date['day'] : 0;
70: $trail = array();
71:
72:
73: if (!empty($year)) {
74: if (!empty($day)) {
75: $date = new Horde_Date($this->_date);
76: $text = $date->strftime('%e');
77:
78: $navdata = array(
79: 'view' => 'Gallery',
80: 'gallery' => $this->_gallery->id,
81: 'slug' => $this->_gallery->get('slug'),
82: 'year' => $year,
83: 'month' => $month,
84: 'day' => $day);
85: $trail[] = array('title' => $text, 'navdata' => $navdata);
86: }
87:
88: if (!empty($month)) {
89: $date = new Horde_Date(
90: array(
91: 'year' => $year,
92: 'month' => $month,
93: 'day' => 1));
94: $text = $date->strftime('%B');
95: $navdata = array(
96: 'view' => 'Gallery',
97: 'gallery' => $this->_gallery->id,
98: 'slug' => $this->_gallery->get('slug'),
99: 'year' => $year,
100: 'month' => $month);
101: $trail[] = array('title' => $text, 'navdata' => $navdata);
102: }
103:
104: $navdata = array(
105: 'view' => 'Gallery',
106: 'gallery' => $this->_gallery->id,
107: 'slug' => $this->_gallery->get('slug'),
108: 'year' => $year);
109: $trail[] = array('title' => $year, 'navdata' => $navdata);
110: } else {
111:
112: $navdata = array(
113: 'view' => 'Gallery',
114: 'gallery' => $this->_gallery->id,
115: 'slug' => $this->_gallery->get('slug'));
116: $trail[] = array('title' => _("All dates"), 'navdata' => $navdata);
117: }
118:
119: $text = htmlspecialchars($this->_gallery->get('name'));
120: $navdata = array(
121: 'view' => 'Gallery',
122: 'gallery' => $this->_gallery->id,
123: 'slug' => $this->_gallery->get('slug'));
124: $trail[] = array('title' => $text, 'navdata' => $navdata);
125:
126: return $trail;
127: }
128:
129: 130: 131: 132: 133:
134: public function getDate()
135: {
136: return $this->_date;
137: }
138:
139: 140: 141: 142: 143:
144: public function setDate($date = array())
145: {
146: $this->_date = $date;
147: }
148:
149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160:
161: public function getGalleryChildren(
162: $perm = Horde_Perms::SHOW, $from = 0, $to = 0, $noauto = false)
163: {
164:
165: static $children = array();
166:
167: $fullkey = md5($noauto . $perm . $this->_gallery->id . serialize($this->_date) . 0 . 0);
168: $cache_key = md5($noauto . $perm . $this->_gallery->id . serialize($this->_date) . $from . $to);
169: if (!empty($children[$cache_key])) {
170: return $children[$cache_key];
171: } elseif (!empty($children[$fullkey])) {
172: return $this->_getArraySlice($children[$fullkey], $from, $to, true);
173: }
174:
175: $ansel_storage = $GLOBALS['injector']->getInstance('Ansel_Storage');
176:
177:
178: $this->_loadSubGalleries();
179: $params = array(
180: 'fields' => array('image_id', 'image_original_date')
181: );
182: if (count($this->_subGalleries)) {
183: $params['gallery_id'] = array_merge(
184: $this->_subGalleries,
185: array($this->_gallery->id));
186: } else {
187: $params['gallery_id'] = $this->_gallery->id;
188: }
189: $sorted_dates = array();
190:
191:
192: if (!count($this->_date) || empty($this->_date['year'])) {
193:
194: $images = $ansel_storage->listImages($params);
195: $dates = array();
196: foreach ($images as $key => $image) {
197: $dates[date('Y', $image['image_original_date'])][] = $key;
198: }
199: $keys = array_keys($dates);
200:
201:
202: if (!$noauto && count($keys) == 1) {
203: $this->_date['year'] = array_pop($keys);
204: return $this->getGalleryChildren($perm, $from, $to, $noauto);
205: }
206:
207: sort($keys, SORT_NUMERIC);
208: foreach ($keys as $key) {
209: $sorted_dates[$key] = $dates[$key];
210: }
211: $display_unit = 'year';
212: } elseif (empty($this->_date['month'])) {
213:
214: $start = new Horde_Date(
215: array(
216: 'year' => $this->_date['year'],
217: 'month' => 1,
218: 'day' => 1)
219: );
220:
221:
222: $end = new Horde_Date($start);
223: $end->mday = 31;
224: $end->month = 12;
225: $end->hour = 23;
226: $end->min = 59;
227: $end->sec = 59;
228:
229:
230: $params['filter'] = array(
231: array(
232: 'property' => 'originalDate',
233: 'op' => '<=',
234: 'value' => (int)$end->timestamp()
235: ),
236: array(
237: 'property' => 'originalDate',
238: 'op' => '>=',
239: 'value' => (int)$start->timestamp()
240: )
241: );
242: $images= $ansel_storage->listImages($params);
243: $dates = array();
244: foreach ($images as $key => $image) {
245: $dates[date('n', $image['image_original_date'])][] = $key;
246: }
247: $keys = array_keys($dates);
248:
249:
250: if (!$noauto && count($keys) == 1) {
251: $this->_date['month'] = array_pop($keys);
252: return $this->getGalleryChildren($perm, $from, $to, $noauto);
253: }
254:
255: sort($keys, SORT_NUMERIC);
256: foreach ($keys as $key) {
257: $sorted_dates[$key] = $dates[$key];
258: }
259: $display_unit = 'month';
260: } elseif (empty($this->_date['day'])) {
261:
262: $start = new Horde_Date(
263: array(
264: 'year' => $this->_date['year'],
265: 'month' => $this->_date['month'],
266: 'day' => 1)
267: );
268:
269:
270: $end = new Horde_Date($start);
271: $end->mday = Horde_Date_Utils::daysInMonth($end->month, $end->year);
272: $end->hour = 23;
273: $end->min = 59;
274: $end->sec = 59;
275:
276: $params['filter'] = array(
277: array(
278: 'property' => 'originalDate',
279: 'op' => '<=',
280: 'value' => (int)$end->timestamp()
281: ),
282: array(
283: 'property' => 'originalDate',
284: 'op' => '>=',
285: 'value' => (int)$start->timestamp()
286: )
287: );
288: $images= $ansel_storage->listImages($params);
289: $dates = array();
290: foreach ($images as $key => $image) {
291: $dates[date('d', $image['image_original_date'])][] = $key;
292: }
293: $keys = array_keys($dates);
294:
295:
296: if (!$noauto && count($keys) == 1) {
297: $this->_date['day'] = array_pop($keys);
298: return $this->getGalleryChildren($perm, $from, $to, $noauto);
299: }
300:
301: sort($keys, SORT_NUMERIC);
302: foreach ($keys as $key) {
303: $sorted_dates[$key] = $dates[$key];
304: }
305: $dates = $sorted_dates;
306: $display_unit = 'day';
307: } else {
308:
309: $start = new Horde_Date($this->_date);
310:
311:
312: $end = new Horde_Date($start->timestamp());
313: $end->hour = 23;
314: $end->min = 59;
315: $end->sec = 59;
316:
317:
318: $params['filter'] = array(
319: array(
320: 'property' => 'originalDate',
321: 'op' => '<=',
322: 'value' => (int)$end->timestamp()
323: ),
324: array(
325: 'property' => 'originalDate',
326: 'op' => '>=',
327: 'value' => (int)$start->timestamp()
328: )
329: );
330:
331:
332: $params['offset'] = $from;
333: $params['limit'] = $to;
334:
335:
336: unset($params['fields']);
337:
338:
339: $images = $ansel_storage->listImages($params);
340: if ($images) {
341: $results = $ansel_storage->getImages(
342: array('ids' => $images, 'preserve' => true));
343: } else {
344: $results = array();
345: }
346:
347: if ($this->_gallery->get('has_subgalleries')) {
348: $images = array();
349: foreach ($results as $id => $image) {
350: $image->gallery = $this->_gallery->id;
351: $images[$id] = $image;
352: }
353: $children[$cache_key] = $images;
354: } else {
355: $children[$cache_key] = $results;
356: }
357:
358: return $children[$cache_key];
359: }
360:
361: $results = array();
362: foreach ($sorted_dates as $key => $images) {
363:
364: switch ($display_unit) {
365: case 'year':
366: $date = array('year' => $key);
367: break;
368: case 'month':
369: $date = array(
370: 'year' => $this->_date['year'],
371: 'month' => (int)$key);
372: break;
373: case 'day':
374: $date = array(
375: 'year' => (int)$this->_date['year'],
376: 'month' => (int)$this->_date['month'],
377: 'day' => (int)$key);
378: }
379:
380: $obj = new Ansel_Gallery_Decorator_Date($this->_gallery, $images);
381: $obj->setDate($date);
382: $results[$key] = $obj;
383: }
384:
385: $children[$cache_key] = $results;
386: if ($from > 0 || $to > 0) {
387: return $this->_getArraySlice($results, $from, $to, true);
388: }
389:
390: return $results;
391: }
392:
393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407:
408: public function countGalleryChildren($perm = Horde_Perms::SHOW,
409: $galleries_only = false, $noauto = true)
410: {
411: $results = $this->getGalleryChildren($perm, 0, 0, $noauto);
412: return count($results);
413: }
414:
415: 416: 417: 418: 419: 420: 421: 422: 423: 424:
425: public function listImages($from = 0, $count = 0)
426: {
427:
428: $children = $this->getGalleryChildren();
429:
430:
431: if (!empty($this->_date['day'])) {
432: $images = array_keys($children);
433: } else {
434: $images = array();
435:
436: foreach ($children as $child) {
437: $images = array_merge($images, $child->getImagesByGrouping());
438: }
439: }
440:
441: return $this->_getArraySlice($images, $from, $count);
442: }
443:
444: 445: 446: 447: 448: 449: 450: 451: 452: 453:
454: public function moveImagesTo($images, $gallery)
455: {
456: if (!$gallery->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) {
457: throw new Horde_Exception_PermissionDenied(sprintf(_("Access denied moving photos to \"%s\"."), $newGallery->get('name')));
458: } elseif (!$this->_gallery->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) {
459: throw new Horde_Exception_PermissionDenied(sprintf(_("Access denied removing photos from \"%s\"."), $gallery->get('name')));
460: }
461:
462:
463: $ids = array();
464: foreach ($images as $imageId) {
465: $ids[] = (int)$imageId;
466: if ($imageId == $this->_gallery->get('default')) {
467: $this->_gallery->set('default', null, true);
468: }
469: }
470:
471: 472: 473: 474:
475: if ($this->_gallery->get('has_subgalleries')) {
476: $gallery_ids = array();
477: $images = $GLOBALS['injector']->getInstance('Ansel_Storage')->getImages(array('ids' => $ids));
478: foreach ($images as $image) {
479: if (empty($gallery_ids[$image->gallery])) {
480: $gallery_ids[$image->gallery] = 1;
481: } else {
482: $gallery_ids[$image->gallery]++;
483: }
484: }
485: }
486:
487:
488: $GLOBALS['injector']->getInstance('Ansel_Storage')->setImagesGallery($ids, $gallery->id);
489:
490:
491: if ($this->_gallery->get('has_subgalleries')) {
492: foreach ($gallery_ids as $id => $count) {
493: $GLOBALS['injector']->getInstance('Ansel_Storage')
494: ->getGallery($id)
495: ->updateImageCount($count, false);
496: }
497: } else {
498: $this->_gallery->updateImageCount(count($ids), false);
499: }
500: $gallery->updateImageCount(count($ids), true);
501:
502:
503: if ($GLOBALS['conf']['ansel_cache']['usecache']) {
504: $GLOBALS['injector']->getInstance('Horde_Cache')->expire('Ansel_Gallery' . $gallery->id);
505: $GLOBALS['injector']->getInstance('Horde_Cache')->expire('Ansel_Gallery' . $this->_gallery->id);
506: }
507:
508: return count($ids);
509: }
510:
511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521:
522: public function removeImage($image, $isStack)
523: {
524:
525: if (!($image instanceof Ansel_Image)) {
526: $image = $GLOBALS['injector']
527: ->getInstance('Ansel_Storage')
528: ->getImage($image);
529: }
530:
531:
532: $image_gallery = abs($image->gallery);
533:
534:
535: if ($image_gallery != $this->_gallery->id) {
536: $this->_loadSubGalleries();
537: if (!in_array($image_gallery, $this->_subGalleries)) {
538: throw new Horde_Exception_NotFound(_("Image not found in gallery."));
539: }
540: }
541:
542:
543: if ($this->_gallery->get('default') == $image->id) {
544: $this->_gallery->set('default', null);
545: $this->_gallery->set('default_type' , 'auto');
546: }
547:
548:
549: $image->deleteCache();
550:
551:
552: try {
553: $GLOBALS['injector']->getInstance('Horde_Core_Factory_Vfs')->create('images')->deleteFile($image->getVFSPath('full'),
554: $image->getVFSName('full'));
555: } catch (Horde_Vfs_Exception $e) {}
556:
557:
558: $GLOBALS['injector']->getInstance('Ansel_Storage')->removeImage($image->id);
559:
560: if (!$isStack) {
561: $GLOBALS['injector']->getInstance('Ansel_Storage')
562: ->getGallery($image_gallery)
563: ->updateImageCount(1, false);
564: }
565:
566:
567: if (!$isStack) {
568: $this->_gallery->set('last_modified', time());
569: }
570:
571:
572: $this->_gallery->save();
573:
574:
575: $image->setTags(array());
576:
577:
578: if ($image->facesCount) {
579: Ansel_Faces::delete($image);
580: }
581:
582:
583: if (($GLOBALS['conf']['comments']['allow'] == 'all' || ($GLOBALS['conf']['comments']['allow'] == 'authenticated' && $GLOBALS['registry']->getAuth())) &&
584: $GLOBALS['registry']->hasMethod('forums/deleteForum')) {
585: try {
586: $GLOBALS['registry']->call('forums/deleteForum', array('ansel', $image->id));
587: } catch (Horde_Exception $e) {
588: Horde::logMessage($e, 'ERR');
589: return false;
590: }
591: }
592:
593: return true;
594: }
595:
596: 597: 598: 599: 600: 601: 602: 603:
604: public function getImages($from = 0, $count = 0)
605: {
606: if (!empty($this->_date['day'])) {
607:
608:
609: $children = $this->getGalleryChildren(Horde_Perms::SHOW);
610: return $this->_getArraySlice($children, $from, $count, true);
611: } else {
612:
613:
614: return array();
615: }
616: }
617:
618: 619: 620: 621: 622: 623:
624: public function hasSubGalleries()
625: {
626: return false;
627: }
628:
629: 630: 631: 632: 633: 634: 635: 636: 637:
638: public function countImages($subgalleries = false)
639: {
640: return count($this->listImages());
641: }
642:
643: 644: 645: 646: 647: 648: 649: 650:
651: protected function _getArraySlice($array, $from, $count, $preserve = false)
652: {
653: if ($from == 0 && $count == 0) {
654: return $array;
655: }
656:
657: return array_slice($array, $from, $count, $preserve);
658: }
659:
660: 661: 662: 663:
664: protected function _loadSubGalleries()
665: {
666:
667:
668:
669: if (!is_array($this->_subGalleries)) {
670: $this->_subGalleries = array();
671: $subs = $GLOBALS['injector']
672: ->getInstance('Ansel_Storage')
673: ->listGalleries(array('parent' => $this->_gallery->id));
674: foreach ($subs as $sub) {
675: $this->_subGalleries[] = $sub->id;
676: }
677: }
678: }
679: }
680: