Overview

Packages

  • Ansel
  • None

Classes

  • Ansel
  • Ansel_Ajax_Application
  • Ansel_Ajax_Imple_EditCaption
  • Ansel_Ajax_Imple_EditFaces
  • Ansel_Ajax_Imple_EditGalleryFaces
  • Ansel_Ajax_Imple_Embed
  • Ansel_Ajax_Imple_GallerySlugCheck
  • Ansel_Ajax_Imple_ImageSaveGeotag
  • Ansel_Ajax_Imple_LocationAutoCompleter
  • Ansel_Ajax_Imple_MapLayerSelect
  • Ansel_Ajax_Imple_TagActions
  • Ansel_Ajax_Imple_ToggleGalleryActions
  • Ansel_Ajax_Imple_ToggleOtherGalleries
  • Ansel_Ajax_Imple_UploadNotification
  • Ansel_Api
  • Ansel_Exception
  • Ansel_Faces
  • Ansel_Faces_Base
  • Ansel_Faces_Facedetect
  • Ansel_Faces_User
  • Ansel_Factory_Faces
  • Ansel_Factory_Storage
  • Ansel_Factory_Styles
  • Ansel_Form_Ecard
  • Ansel_Form_Image
  • Ansel_Form_ImageDate
  • Ansel_Form_Upload
  • Ansel_Gallery
  • Ansel_Gallery_Decorator_Date
  • Ansel_GalleryMode_Base
  • Ansel_GalleryMode_Date
  • Ansel_GalleryMode_Normal
  • Ansel_Image
  • Ansel_ImageGenerator
  • Ansel_ImageGenerator_Mini
  • Ansel_ImageGenerator_PolaroidThumb
  • Ansel_ImageGenerator_PolaroidThumbStack
  • Ansel_ImageGenerator_RoundedThumb
  • Ansel_ImageGenerator_RoundedThumbStack
  • Ansel_ImageGenerator_Screen
  • Ansel_ImageGenerator_ShadowThumb
  • Ansel_ImageGenerator_ShadowThumbStack
  • Ansel_ImageGenerator_SquareThumb
  • Ansel_ImageGenerator_Thumb
  • Ansel_LoginTasks_SystemTask_Upgrade
  • Ansel_Report
  • Ansel_Report_letter
  • Ansel_Report_mail
  • Ansel_Report_tickets
  • Ansel_Search
  • Ansel_Search_exif
  • Ansel_Search_Tag
  • Ansel_Storage
  • Ansel_Style
  • Ansel_Tagger
  • Ansel_Test
  • Ansel_Tile_DateGallery
  • Ansel_Tile_Gallery
  • Ansel_Tile_Image
  • Ansel_View_Ansel
  • Ansel_View_Base
  • Ansel_View_EmbeddedRenderer_GalleryLink
  • Ansel_View_EmbeddedRenderer_Mini
  • Ansel_View_EmbeddedRenderer_Slideshow
  • Ansel_View_Gallery
  • Ansel_View_GalleryProperties
  • Ansel_View_GalleryRenderer_Base
  • Ansel_View_GalleryRenderer_Gallery
  • Ansel_View_GalleryRenderer_GalleryLightbox
  • Ansel_View_Image
  • Ansel_View_List
  • Ansel_View_Results
  • Ansel_View_Slideshow
  • Ansel_View_Upload
  • Ansel_Widget
  • Ansel_Widget_Actions
  • Ansel_Widget_Base
  • Ansel_Widget_GalleryFaces
  • Ansel_Widget_Geotag
  • Ansel_Widget_ImageFaces
  • Ansel_Widget_Links
  • Ansel_Widget_OtherGalleries
  • Ansel_Widget_OwnerFaces
  • Ansel_Widget_SimilarPhotos
  • Ansel_Widget_Tags
  • Ansel_XPPublisher
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Ansel_View_Image:: class wraps display of individual images.
  4:  *
  5:  * See the enclosed file COPYING for license information (GPL). If you
  6:  * did not receive this file, see http://www.horde.org/licenses/gpl.
  7:  *
  8:  * @author  Chuck Hagenbuch <chuck@horde.org>
  9:  * @author  Michael J. Rubinsky <mrubinsk@horde.org>
 10:  *
 11:  * @package Ansel
 12:  */
 13: class Ansel_View_Image extends Ansel_View_Ansel
 14: {
 15: 
 16:     protected $_slug;
 17:     protected $_page;
 18:     protected $_date;
 19:     protected $_mode;
 20:     protected $_style;
 21:     protected $_geometry;
 22:     protected $_imageList;
 23:     protected $_revList;
 24:     protected $_urls = array();
 25: 
 26:     /**
 27:      * Const'r
 28:      *
 29:      */
 30:     public function __construct($params = array())
 31:     {
 32:         parent::__construct($params);
 33: 
 34:         /* Get the Ansel_Image */
 35:         $image = $GLOBALS['injector']->getInstance('Ansel_Storage')->getImage($params['image_id']);
 36: 
 37:         /* Get the Ansel_Gallery */
 38:         $this->gallery = $this->_getGallery();
 39: 
 40:         /* Save the image reference */
 41:         $this->resource = $image;
 42: 
 43:         /* Check user age */
 44:         if (!$this->gallery->isOldEnough()) {
 45:             if (!empty($params['api'])) {
 46:                throw new Horde_Exception('Locked galleries are not viewable via the api.');
 47:             }
 48:             $date = Ansel::getDateParameter(
 49:                 array('year' => isset($this->_params['year']) ? $this->_params['year'] : 0,
 50:                       'month' => isset($this->_params['month']) ? $this->_params['month'] : 0,
 51:                       'day' => isset($this->_params['day']) ? $this->_params['day'] : 0));
 52: 
 53:                 $url = Ansel::getUrlFor('view', array_merge(
 54:                     array('gallery' => $this->gallery->id,
 55:                           'slug' => empty($params['slug']) ? '' : $params['slug'],
 56:                           'page' => empty($params['page']) ? 0 : $params['page'],
 57:                           'view' => 'Image',
 58:                           'image' => $image->id),
 59:                     $date),
 60:                     true);
 61: 
 62:             $params = array('gallery' => $this->gallery->id, 'url' => $url);
 63: 
 64:             Horde::url('disclamer.php')->add($params)->setRaw(true)->redirect();
 65:             exit;
 66:         }
 67: 
 68:         // Check password
 69:         if ($this->gallery->hasPasswd()) {
 70:             if (!empty($params['api'])) {
 71:                 return PEAR::raiseError(_("Locked galleries are not viewable via the api."));
 72:             }
 73:             $date = Ansel::getDateParameter(
 74:                 array('year' => isset($this->_params['year']) ? $this->_params['year'] : 0,
 75:                       'month' => isset($this->_params['month']) ? $this->_params['month'] : 0,
 76:                       'day' => isset($this->_params['day']) ? $this->_params['day'] : 0));
 77: 
 78:                 $url = Ansel::getUrlFor('view', array_merge(
 79:                     array('gallery' => $this->gallery->id,
 80:                           'slug' => empty($params['slug']) ? '' : $params['slug'],
 81:                           'page' => empty($params['page']) ? 0 : $params['page'],
 82:                           'view' => 'Image',
 83:                           'image' => $image->id),
 84:                     $date),
 85:                     true);
 86: 
 87:             $params = array('gallery' => $this->gallery->id, 'url' => $url);
 88: 
 89:             Horde::url('protect.php')->add($params)->setRaw(true)->redirect();
 90:             exit;
 91:         }
 92: 
 93:         /* Any script files we may need if not calling via the api */
 94:         if (empty($this->_params['api'])) {
 95:             Horde::addScriptFile('effects.js', 'horde');
 96:             Horde::addScriptFile('stripe.js', 'horde');
 97:         }
 98: 
 99:     }
100: 
101:     public function getGalleryCrumbData()
102:     {
103:         return $this->gallery->getGalleryCrumbData();
104:     }
105: 
106:     /**
107:      * Get the title for this view.
108:      *
109:      * @return string  The title.
110:      */
111:     public function getTitle()
112:     {
113:         return $this->resource->filename;
114:     }
115: 
116:     /**
117:      * Get the HTML representing this view.
118:      *
119:      * @return string  The HTML.
120:      */
121:     public function html()
122:     {
123:         $this->_prepare();
124:         return $this->_html();
125:     }
126: 
127:     /**
128:      * Build variables needed to output the html
129:      *
130:      * @return void
131:      */
132:     protected function _prepare()
133:     {
134:         /* Gallery slug and the page this image is one, if specified */
135:         $this->_page = isset($this->_params['page']) ? $this->_params['page'] : 0;
136:         $this->_slug = $this->gallery->get('slug');
137: 
138:         /* Get any date info the gallery has */
139:         $this->_date = $this->gallery->getDate();
140: 
141:         $this->_style = (empty($this->_params['style']) ?
142:              $this->gallery->getStyle() :
143:              $this->_params['style']);
144: 
145:         /* Make sure the screen view is loaded and get the geometry */
146:         try {
147:             $this->_geometry = $this->resource->getDimensions('screen');
148:         } catch (Horde_Exception $e) {
149:             Horde::logMessage($e, 'ERR');
150:             $this->_geometry = $GLOBALS['conf']['screen'];
151:         }
152: 
153:         /* Get the image lists */
154:         $this->_imageList = $this->gallery->listImages();
155:         $this->_revList = array_flip($this->_imageList);
156: 
157:         /* Not needed when being called via api */
158:         if (empty($this->_params['api'])) {
159:             $this->_urls['ecard'] = Horde::url('img/ecard.php')->add(
160:                 array_merge(array('gallery' => $this->gallery->id,
161:                                   'image' => $this->resource->id),
162:                             $this->_date));
163: 
164:             /* Build the various urls */
165:             $imageActionUrl = Horde::url('image.php')->add(
166:                 array_merge(array('gallery' => $this->gallery->id,
167:                                   'image' => $this->resource->id,
168:                                   'page' => $this->_page),
169:                             $this->_date));
170: 
171:             /* Create the popup code seperately to avoid encoding issues */
172:             $this->_urls['prop_popup'] = Horde::popupJs(
173:               $imageActionUrl,
174:               array('params' => array('actionID' => 'modify',
175:                                       'ret' => 'image',
176:                                       'gallery' => $this->gallery->id,
177:                                       'image' => $this->resource->id,
178:                                       'page' => $this->_page),
179:                     'urlencode' => true));
180: 
181:             $this->_urls['edit'] = $imageActionUrl->copy()->add('actionID', 'editimage');
182:             $this->_urls['delete'] = $imageActionUrl->copy()->add('actionID', 'delete');
183:             $this->_urls['download'] = Horde::url('img/download.php', true)->add('image', $this->resource->id);
184:             $this->_urls['report'] = Horde::url('report.php')->add(
185:                     array('gallery' =>  $this->gallery->id,
186:                           'image' => $this->resource->id));
187:         }
188: 
189:         /* Check for an explicit gallery view url to use */
190:         if (!empty($this->_params['gallery_view_url'])) {
191:             $this->_urls['gallery'] = new Horde_Url(str_replace(array('%g', '%s'), array($this->gallery->id, $this->_slug), urldecode($this->_params['gallery_view_url'])));
192:             $this->_urls['gallery']->add($this->_date);
193:         } else {
194:             $this->_urls['gallery'] = Ansel::getUrlFor('view', array_merge(
195:                                            array('gallery' => $this->gallery->id,
196:                                                  'slug' => $this->_slug,
197:                                                  'page' => $this->_page,
198:                                                  'view' => 'Gallery'),
199:                                            $this->_date),
200:                                            true);
201:         }
202: 
203:         /* Get the image src url */
204:         $this->_urls['imgsrc'] = Ansel::getImageUrl($this->resource->id, 'screen', true, $this->_style);
205: 
206:         /* And a self url. Can't use Horde::selfUrl() since that would ignore
207:          * pretty urls. */
208:         $this->_urls['self'] = Ansel::getUrlFor('view', array_merge(
209:                                     array('gallery' => $this->gallery->id,
210:                                           'slug' => $this->_slug,
211:                                           'image' => $this->resource->id,
212:                                           'view' => 'Image',
213:                                           'page' => $this->_page),
214:                                     $this->_date));
215:     }
216: 
217:     /**
218:      * Image view specific HTML - done so we can extend View_Image for things
219:      * like the slideshow view etc...
220:      */
221:     protected function _html()
222:     {
223:         global $conf, $registry, $prefs;
224: 
225:         /* Starting image */
226:         $imageIndex = $this->_revList[$this->resource->id];
227: 
228:         /* Get comments before any output in sent. */
229:         if (($conf['comments']['allow'] == 'all' || ($conf['comments']['allow'] == 'authenticated' && $GLOBALS['registry']->getAuth())) &&
230:             $registry->hasMethod('forums/doComments')) {
231:             $hasComments = true;
232:             if (!empty($this->_params['comment_url'])) {
233:                 $this->_params['comment_url'] = str_replace(
234:                     array('%i', '%g', '%s'),
235:                     array($imageId, $galleryId, $gallerySlug),
236:                     urldecode($this->_params['comment_url']));
237:             }
238:             $url = empty($this->_params['comment_url']) ? null : $this->_params['comment_url'];
239:             try {
240:                 $comments = $registry->forums->doComments(
241:                   'ansel', $this->resource->id, 'commentCallback', true, null, $url);
242:             } catch (Horde_Exception $e) {
243:                 Horde::logMessage($e, 'DEBUG');
244:                 $comments = array();
245:             }
246:         } else {
247:             $comments = array();
248:             $hasComments = false;
249:         }
250:         /* Get the next and previous image ids */
251:         if (isset($this->_imageList[$imageIndex + 1])) {
252:             $next = $this->_imageList[$imageIndex + 1];
253:         } else {
254:             $next = $this->_imageList[0];
255:         }
256:         if (isset($this->_imageList[$imageIndex - 1])) {
257:             $prev = $this->_imageList[$imageIndex - 1];
258:         } else {
259:             $prev = $this->_imageList[count($this->_imageList) - 1];
260:         }
261: 
262:         /* Calculate the page number of the next/prev images */
263:         $perpage = $prefs->getValue('tilesperpage');
264:         $pagestart = $this->_page * $perpage;
265:         $pageend = min(count($this->_imageList), $pagestart + $perpage - 1);
266:         $page_next = $this->_page;
267: 
268:         if ($this->_revList[$this->resource->id] + 1 > $pageend) {
269:             $page_next++;
270:         }
271:         $page_prev = $this->_page;
272:         if ($this->_revList[$this->resource->id] - 1 < $pagestart) {
273:             $page_prev--;
274:         }
275: 
276:         /* Previous image link */
277:         if (!empty($this->_params['image_view_url'])) {
278:             $prev_url = str_replace(
279:                 array('%i', '%g', '%s'),
280:                 array($prev, $this->gallery->id, $this->_slug),
281:                 urldecode($this->_params['image_view_url']));
282:         } else {
283:             $prev_url = Ansel::getUrlFor('view', array_merge(
284:                 array('gallery' => $this->gallery->id,
285:                       'slug' => $this->_slug,
286:                       'image' => $prev,
287:                       'view' => 'Image',
288:                       'page' => $page_prev),
289:                 $this->_date));
290:         }
291:         $prvImgUrl = Ansel::getImageUrl($prev, 'screen', true, $this->_style);
292: 
293:         /* Next image link */
294:         if (!empty($this->_params['image_view_url'])) {
295:             $next_url = str_replace(
296:                 array('%i', '%g', '%s'),
297:                 array($prev, $this->gallery->id, $this->_slug),
298:                 urldecode($this->_params['image_view_url']));
299:         } else {
300:             $next_url = Ansel::getUrlFor('view', array_merge(
301:                 array('gallery' => $this->gallery->id,
302:                       'slug' => $this->_slug,
303:                       'image' => $next,
304:                       'view' => 'Image',
305:                       'page' => $page_next),
306:                 $this->_date));
307:         }
308:         $nextImgUrl = Ansel::getImageUrl($next, 'screen', true, $this->_style);
309: 
310:         /* Slideshow link */
311:         if (!empty($this->_params['slideshow_link'])) {
312:             $this->_urls['slideshow'] = str_replace(array('%i', '%g'),
313:                                          array($this->resource->id, $this->gallery->id),
314:                                          urldecode($this->_params['slideshow_link']));
315:         } else {
316:             $this->_urls['slideshow'] = Horde::url('view.php')->add(
317:                 array_merge(array('gallery' => $this->gallery->id,
318:                                   'image' => $this->resource->id,
319:                                   'view' => 'Slideshow'),
320:                             $this->_date));
321:         }
322: 
323:         $commentHtml = '';
324:         if (isset($hasComments)) {
325:             if (!empty($comments['threads'])) {
326:                 $commentHtml .= '<br />' . $comments['threads'];
327:             }
328:             if (!empty($comments['comments'])) {
329:                 $commentHtml .= '<br />' . $comments['comments'];
330:             }
331:         }
332: 
333:         if ($prefs->getValue('showexif')) {
334:             $exifHtml = $this->_getExifHtml();
335:         } else {
336:             $exifHtml = '';
337:         }
338: 
339:         /* Buffer the template file and return the html */
340:         Horde::startBuffer();
341: 
342:         //@TODO: Refactor styles to allow dynamic inclusion/exclusion of widgets.
343:         /* These items currently don't work when viewing through the api */
344:         if (empty($this->_params['api'])) {
345:             /* Add the widgets */
346:             // Tag widget
347:             $this->addWidget(Ansel_Widget::factory('Tags', array('view' => 'image')));
348: 
349:             // Similar photos
350:             $this->addWidget(Ansel_Widget::factory('SimilarPhotos'));
351: 
352:            // Geolocation
353:            $this->addWidget(Ansel_Widget::factory('Geotag', array('images' => array($this->resource->id))));
354: 
355:             // Faces
356:             if ($conf['faces']['driver']) {
357:                 $this->addWidget(Ansel_Widget::factory('ImageFaces', array('selfUrl' => $this->_urls['self'])));
358:             }
359: 
360:             // Links
361:             $this->addWidget(Ansel_Widget::factory('Links', array()));
362: 
363:             /* In line caption editing */
364:             if ($this->gallery->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) {
365:                 $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create(array('ansel', 'EditCaption'), array(
366:                     'width' => $this->_geometry['width'],
367:                     'domid' => "Caption",
368:                     'id' => $this->resource->id
369:                 ));
370:             }
371:         }
372: 
373:         /* Output the js if we are calling via the api */
374:         if (!empty($this->_params['api'])) {
375:             $includes = $GLOBALS['injector']->createInstance('Horde_Script_Files');
376:             $includes->add('effects.js', 'horde',true, true);
377:             $includes->add('stripe.js', 'horde', true, true);
378:             $includes->includeFiles();
379:         }
380: 
381:         require ANSEL_TEMPLATES . '/view/image.inc';
382:         return Horde::endBuffer();
383:     }
384: 
385:     /**
386:      * Helper function for generating the HTML for EXIF data.
387:      *
388:      * @return string  The HTML
389:      */
390:     private function _getExifHtml()
391:     {
392:         $data = $this->resource->getAttributes(true);
393: 
394:         $html = '';
395:         if (count($data)) {
396:             $data = array_chunk($data, 3);
397:             $html .= '<table class="box striped" cellspacing="0" style="width:100%; padding:4px">';
398:             $i = 0;
399:             foreach ($data as $elem) {
400:                 $html .= '<tr class="' . (($i++ % 2 == 0) ? 'rowEven' : 'rowOdd')
401:                          . '">' . implode('', $elem) . '</tr>';
402:             }
403:             $html .= '</table>';
404:         }
405:         return $html;
406:     }
407: 
408:     public function viewType()
409:     {
410:         return 'Image';
411:     }
412: 
413: }
414: 
API documentation generated by ApiGen