aboutsummaryrefslogtreecommitdiff
path: root/mod/lightpics/classes
diff options
context:
space:
mode:
Diffstat (limited to 'mod/lightpics/classes')
-rw-r--r--mod/lightpics/classes/TidypicsAlbum.php375
-rw-r--r--mod/lightpics/classes/TidypicsImage.php406
2 files changed, 781 insertions, 0 deletions
diff --git a/mod/lightpics/classes/TidypicsAlbum.php b/mod/lightpics/classes/TidypicsAlbum.php
new file mode 100644
index 000000000..0cb8bd84e
--- /dev/null
+++ b/mod/lightpics/classes/TidypicsAlbum.php
@@ -0,0 +1,375 @@
+<?php
+/**
+ * Tidypics Album class
+ *
+ * @package TidypicsAlbum
+ * @author Cash Costello
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2
+ */
+
+
+class TidypicsAlbum extends ElggObject {
+ /**
+ * Sets the internal attributes
+ */
+ protected function initializeAttributes() {
+ parent::initializeAttributes();
+
+ $this->attributes['subtype'] = "album";
+ }
+
+ /**
+ * Constructor
+ * @param mixed $guid
+ */
+ public function __construct($guid = null) {
+ parent::__construct($guid);
+ }
+
+ /**
+ * Save an album
+ *
+ * @return bool
+ */
+ public function save() {
+
+ if (!isset($this->new_album)) {
+ $this->new_album = true;
+ }
+
+ if (!isset($this->last_notified)) {
+ $this->last_notified = 0;
+ }
+
+ if (!parent::save()) {
+ return false;
+ }
+
+ mkdir(tp_get_img_dir() . $this->guid, 0755, true);
+
+ elgg_trigger_event('create', 'album', $this);
+
+ return true;
+ }
+
+ /**
+ * Delete album
+ *
+ * @return bool
+ */
+ public function delete() {
+
+ $this->deleteImages();
+ $this->deleteAlbumDir();
+
+ return parent::delete();
+ }
+
+ /**
+ * Get the title of the photo album
+ *
+ * @return string
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * Get the URL for this album
+ *
+ * @return string
+ */
+ public function getURL() {
+ $title = elgg_get_friendly_title($this->getTitle());
+ $url = "photos/album/$this->guid/$title";
+ return elgg_normalize_url($url);
+ }
+
+ /**
+ * Get an array of image objects
+ *
+ * @param int $limit
+ * @param int $offset
+ * @return array
+ */
+ public function getImages($limit, $offset = 0) {
+ $imageList = $this->getImageList();
+ if ($offset > count($imageList)) {
+ return array();
+ }
+
+ $imageList = array_slice($imageList, $offset, $limit);
+
+ $images = array();
+ foreach ($imageList as $guid) {
+ $images[] = get_entity($guid);
+ }
+ return $images;
+ }
+
+ /**
+ * View a list of images
+ *
+ * @param array $options Options to pass to elgg_view_entity_list()
+ * @return string
+ */
+ public function viewImages(array $options = array()) {
+ $count = $this->getSize();
+
+ if ($count == 0) {
+ return '';
+ }
+
+ $defaults = array(
+ 'count' => $count,
+ 'limit' => 16,
+ 'offset' => max(get_input('offset'), 0),
+ 'full_view' => false,
+ 'list_type' => 'gallery',
+ 'list_type_toggle' => false,
+ 'pagination' => true,
+ 'gallery_class' => 'tidypics-gallery elgg-lightbox-gallery',
+ );
+
+ $options = array_merge($defaults, (array) $options);
+ $images = $this->getImages($options['limit'], $options['offset']);
+
+ if (count($images) == 0) {
+ return '';
+ }
+
+ return elgg_view_entity_list($images, $options);
+ }
+
+ /**
+ * Returns the cover image entity
+ * @return TidypicsImage
+ */
+ public function getCoverImage() {
+ return get_entity($this->getCoverImageGuid());
+ }
+
+ /**
+ * Get the GUID of the album cover
+ *
+ * @return int
+ */
+ public function getCoverImageGuid() {
+ if ($this->getSize() == 0) {
+ return 0;
+ }
+
+ $guid = $this->cover;
+ $imageList = $this->getImageList();
+ if (!in_array($guid, $imageList)) {
+ // select random photo to be cover
+ $index = array_rand($imageList, 1);
+ $guid = $imageList[$index];
+ $this->cover = $guid;
+ }
+ return $guid;
+ }
+
+ /**
+ * Set the GUID for the album cover
+ *
+ * @param int $guid
+ * @return bool
+ */
+ public function setCoverImageGuid($guid) {
+ $imageList = $this->getImageList();
+ if (!in_array($guid, $imageList)) {
+ return false;
+ }
+ $this->cover = $guid;
+ return true;
+ }
+
+ /**
+ * Get the number of photos in the album
+ *
+ * @return int
+ */
+ public function getSize() {
+ return count($this->getImageList());
+ }
+
+ /**
+ * Returns an order list of image guids
+ *
+ * @return array
+ */
+ public function getImageList() {
+ $listString = $this->orderedImages;
+ if (!$listString) {
+ return array();
+ }
+ $list = unserialize($listString);
+
+ // if empty don't need to check the permissions.
+ if (!$list) {
+ return array();
+ }
+
+ // check access levels
+ $guidsString = implode(',', $list);
+
+ $options = array(
+ 'wheres' => array("e.guid IN ($guidsString)"),
+ 'order_by' => "FIELD(e.guid, $guidsString)",
+ 'callback' => 'tp_guid_callback',
+ 'limit' => ELGG_ENTITIES_NO_VALUE
+ );
+
+ $list = elgg_get_entities($options);
+ return $list;
+ }
+
+ /**
+ * Sets the album image order
+ *
+ * @param array $list An indexed array of image guids
+ * @return bool
+ */
+ public function setImageList($list) {
+ // validate data
+ foreach ($list as $guid) {
+ if (!filter_var($guid, FILTER_VALIDATE_INT)) {
+ return false;
+ }
+ }
+
+ $listString = serialize($list);
+ $this->orderedImages = $listString;
+ return true;
+ }
+
+ /**
+ * Add new images to the front of the image list
+ *
+ * @param array $list An indexed array of image guids
+ * @return bool
+ */
+ public function prependImageList($list) {
+ $currentList = $this->getImageList();
+ $list = array_merge($list, $currentList);
+ return $this->setImageList($list);
+ }
+
+ /**
+ * Get the previous image in the album. Wraps around to the last image if given the first.
+ *
+ * @param int $guid GUID of the current image
+ * @return TidypicsImage
+ */
+ public function getPreviousImage($guid) {
+ $imageList = $this->getImageList();
+ $key = array_search($guid, $imageList);
+ if ($key === FALSE) {
+ return null;
+ }
+ $key--;
+ if ($key < 0) {
+ return get_entity(end($imageList));
+ }
+ return get_entity($imageList[$key]);
+ }
+
+ /**
+ * Get the next image in the album. Wraps around to the first image if given the last.
+ *
+ * @param int $guid GUID of the current image
+ * @return TidypicsImage
+ */
+ public function getNextImage($guid) {
+ $imageList = $this->getImageList();
+ $key = array_search($guid, $imageList);
+ if ($key === FALSE) {
+ return null;
+ }
+ $key++;
+ if ($key >= count($imageList)) {
+ return get_entity($imageList[0]);
+ }
+ return get_entity($imageList[$key]);
+ }
+
+ /**
+ * Get the index into the album for a particular image
+ *
+ * @param int $guid GUID of the image
+ * @return int
+ */
+ public function getIndex($guid) {
+ return array_search($guid, $this->getImageList()) + 1;
+ }
+
+ /**
+ * Remove an image from the album list
+ *
+ * @param int $imageGuid
+ * @return bool
+ */
+ public function removeImage($imageGuid) {
+ $imageList = $this->getImageList();
+ $key = array_search($imageGuid, $imageList);
+ if ($key === false) {
+ return false;
+ }
+
+ unset($imageList[$key]);
+ $this->setImageList($imageList);
+
+ return true;
+ }
+
+ /**
+ * Has enough time elapsed between the last_notified and notify_interval setting?
+ *
+ * @return bool
+ */
+ public function shouldNotify() {
+ return time() - $this->last_notified > elgg_get_plugin_setting('notify_interval', 'tidypics');
+ }
+
+ /**
+ * Delete all the images in this album
+ *
+ * @todo ElggBatch?
+ */
+ protected function deleteImages() {
+ $images = elgg_get_entities(array(
+ "type=" => "object",
+ "subtype" => "image",
+ "container_guid" => $this->guid,
+ "limit" => ELGG_ENTITIES_NO_VALUE,
+ ));
+ if ($images) {
+ foreach ($images as $image) {
+ if ($image) {
+ $image->delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Delete the album directory on disk
+ */
+ protected function deleteAlbumDir() {
+ $tmpfile = new ElggFile();
+ $tmpfile->setFilename('image/' . $this->guid . '/._tmp_del_tidypics_album_');
+ $tmpfile->subtype = 'image';
+ $tmpfile->owner_guid = $this->owner_guid;
+ $tmpfile->container_guid = $this->guid;
+ $tmpfile->open("write");
+ $tmpfile->write('');
+ $tmpfile->close();
+ $tmpfile->save();
+ $albumdir = eregi_replace('/._tmp_del_tidypics_album_', '', $tmpfile->getFilenameOnFilestore());
+ $tmpfile->delete();
+ if (is_dir($albumdir)) {
+ rmdir($albumdir);
+ }
+ }
+}
diff --git a/mod/lightpics/classes/TidypicsImage.php b/mod/lightpics/classes/TidypicsImage.php
new file mode 100644
index 000000000..5a8d42ccc
--- /dev/null
+++ b/mod/lightpics/classes/TidypicsImage.php
@@ -0,0 +1,406 @@
+<?php
+/**
+ * Tidypics Image class
+ *
+ * @package TidypicsImage
+ * @author Cash Costello
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2
+ */
+
+
+class TidypicsImage extends ElggFile {
+ protected function initializeAttributes() {
+ parent::initializeAttributes();
+
+ $this->attributes['subtype'] = "image";
+ }
+
+ public function __construct($guid = null) {
+ parent::__construct($guid);
+ }
+
+ /**
+ * Save the image
+ *
+ * @warning container_guid must be set first
+ *
+ * @param array $data
+ * @return bool
+ */
+ public function save($data = null) {
+
+ if (!parent::save()) {
+ return false;
+ }
+
+ if ($data) {
+ // new image
+ $this->simpletype = "image";
+ $this->saveImageFile($data);
+ $this->saveThumbnails();
+ $this->extractExifData();
+ }
+
+ return true;
+ }
+
+ /**
+ * Delete image
+ *
+ * @return bool
+ */
+ public function delete() {
+
+ // check if batch should be deleted
+ $batch = elgg_get_entities_from_relationship(array(
+ 'relationship' => 'belongs_to_batch',
+ 'relationship_guid' => $this->guid,
+ 'inverse_relationship' => false,
+ ));
+ if ($batch) {
+ $batch = $batch[0];
+ $count = elgg_get_entities_from_relationship(array(
+ 'relationship' => 'belongs_to_batch',
+ 'relationship_guid' => $batch->guid,
+ 'inverse_relationship' => true,
+ 'count' => true,
+ ));
+ if ($count == 1) {
+ // last image so delete batch
+ $batch->delete();
+ }
+ }
+
+ $album = get_entity($this->container_guid);
+ if ($album) {
+ $album->removeImage($this->guid);
+ }
+
+ $this->removeThumbnails();
+
+ // update quota
+ $owner = $this->getOwnerEntity();
+ $owner->image_repo_size = (int)$owner->image_repo_size - $this->size();
+
+ return parent::delete();
+ }
+
+ /**
+ * Get the title of the image
+ *
+ * @return string
+ */
+ public function getTitle() {
+ if ($this->title) {
+ return $this->title;
+ } else {
+ return $this->originalfilename;
+ }
+ }
+
+ /**
+ * Get the URL for the web page of this image
+ *
+ * @return string
+ */
+ public function getURL() {
+ $title = elgg_get_friendly_title($this->getTitle());
+ $url = "photos/image/$this->guid/$title";
+ return elgg_normalize_url($url);
+ }
+
+ /**
+ * Get the src URL for the image
+ *
+ * @return string
+ */
+ public function getIconURL($size = 'small') {
+ if ($size == 'tiny') {
+ $size = 'thumb';
+ }
+ return elgg_normalize_url("photos/thumbnail/$this->guid/$size/");
+ }
+
+ /**
+ * Get the view information for this image
+ *
+ * @param $viewer_guid The guid of the viewer
+ * @return array with number of views, number of unique viewers, and number of views for this viewer
+ */
+ public function getViewInfo($viewer_guid = 0) {
+ if ($viewer_guid == 0) {
+ $viewer_guid = elgg_get_logged_in_user_guid();
+ }
+
+ $views = elgg_get_annotations(array(
+ 'guid' => $this->getGUID(),
+ 'annotation_name' => 'tp_view',
+ 'limit' => 0,
+ ));
+ if ($views) {
+ $total_views = count($views);
+
+ if ($this->getOwnerGUID() == $viewer_guid) {
+ // get unique number of viewers
+ $diff_viewers = array();
+ foreach ($views as $view) {
+ $diff_viewers[$view->owner_guid] = 1;
+ }
+ $unique_viewers = count($diff_viewers);
+ } else if ($viewer_guid) {
+ // get the number of times this user has viewed the photo
+ $my_views = 0;
+ foreach ($views as $view) {
+ if ($view->owner_guid == $viewer_guid) {
+ $my_views++;
+ }
+ }
+ }
+
+ $view_info = array("total" => $total_views, "unique" => $unique_viewers, "mine" => $my_views);
+ }
+ else {
+ $view_info = array("total" => 0, "unique" => 0, "mine" => 0);
+ }
+
+ return $view_info;
+ }
+
+ /**
+ * Add a view to this image
+ *
+ * @param $viewer_guid
+ * @return void
+ */
+ public function addView($viewer_guid = 0) {
+ if ($viewer_guid == 0) {
+ $viewer_guid = elgg_get_logged_in_user_guid();
+ }
+
+ if ($viewer_guid != $this->owner_guid && tp_is_person()) {
+ create_annotation($this->getGUID(), "tp_view", "1", "integer", $viewer_guid, ACCESS_PUBLIC);
+ }
+ }
+
+
+ /**
+ * Set the internal filenames
+ */
+ protected function setOriginalFilename($originalName) {
+ $prefix = "image/" . $this->container_guid . "/";
+ $filestorename = elgg_strtolower(time() . $originalName);
+ $this->setFilename($prefix . $filestorename);
+ $this->originalfilename = $originalName;
+ }
+
+ /**
+ * Save the uploaded image
+ *
+ * @param array $data
+ */
+ protected function saveImageFile($data) {
+ $this->checkUploadErrors($data);
+
+ // we need to make sure the directory for the album exists
+ // @note for group albums, the photos are distributed among the users
+ $dir = tp_get_img_dir() . $this->getContainerGUID();
+ if (!file_exists($dir)) {
+ mkdir($dir, 0755, true);
+ }
+
+ // move the uploaded file into album directory
+ $this->setOriginalFilename($data['name']);
+ $filename = $this->getFilenameOnFilestore();
+ $result = move_uploaded_file($data['tmp_name'], $filename);
+ if (!$result) {
+ return false;
+ }
+
+ $owner = $this->getOwnerEntity();
+ $owner->image_repo_size = (int)$owner->image_repo_size + $this->size();
+
+ return true;
+ }
+
+ /**
+ * Need to restore sanity to this function
+ * @param type $data
+ */
+ protected function checkUploadErrors($data) {
+ // check for upload errors
+ if ($data['error']) {
+ if ($data['error'] == 1) {
+ trigger_error('Tidypics warning: image exceeded server php upload limit', E_USER_WARNING);
+ throw new Exception(elgg_echo('tidypics:image_mem'));
+ } else {
+ throw new Exception(elgg_echo('tidypics:unk_error'));
+ }
+ }
+
+ // must be an image
+ if (!tp_upload_check_format($data['type'])) {
+ throw new Exception(elgg_echo('tidypics:not_image'));
+ }
+
+ // make sure file does not exceed memory limit
+ if (!tp_upload_check_max_size($data['size'])) {
+ throw new Exception(elgg_echo('tidypics:image_mem'));
+ }
+
+ // make sure the in memory image size does not exceed memory available
+ $imginfo = getimagesize($data['tmp_name']);
+ if (!tp_upload_memory_check($image_lib, $imginfo[0] * $imginfo[1])) {
+ trigger_error('Tidypics warning: image memory size too large for resizing so rejecting', E_USER_WARNING);
+ throw new Exception(elgg_echo('tidypics:image_pixels'));
+ }
+
+ // make sure file fits quota
+ if (!tp_upload_check_quota($data['size'], elgg_get_logged_in_user_guid())) {
+ throw new Exception(elgg_echo('tidypics:cannot_upload_exceeds_quota'));
+ }
+ }
+
+ /**
+ * Save the image thumbnails
+ */
+ protected function saveThumbnails() {
+ elgg_load_library('tidypics:resize');
+
+ $imageLib = elgg_get_plugin_setting('image_lib', 'tidypics');
+
+ $prefix = "image/" . $this->container_guid . "/";
+ $filename = $this->getFilename();
+ $filename = substr($filename, strrpos($filename, '/') + 1);
+
+ if ($imageLib == 'ImageMagick') {
+ // ImageMagick command line
+ if (tp_create_im_cmdline_thumbnails($this, $prefix, $filename) != true) {
+ trigger_error('Tidypics warning: failed to create thumbnails - ImageMagick command line', E_USER_WARNING);
+ }
+ } else if ($imageLib == 'ImageMagickPHP') {
+ // imagick php extension
+ if (tp_create_imagick_thumbnails($this, $prefix, $filename) != true) {
+ trigger_error('Tidypics warning: failed to create thumbnails - ImageMagick PHP', E_USER_WARNING);
+ }
+ } else {
+ if (tp_create_gd_thumbnails($this, $prefix, $filename) != true) {
+ trigger_error('Tidypics warning: failed to create thumbnails - GD', E_USER_WARNING);
+ }
+ }
+ }
+
+ /**
+ * Get the image data of a thumbnail
+ *
+ * @param string $size
+ * @return string
+ */
+ public function getThumbnail($size) {
+ switch ($size) {
+ case 'thumb':
+ $thumb = $this->thumbnail;
+ break;
+ case 'small':
+ $thumb = $this->smallthumb;
+ break;
+ case 'large':
+ $thumb = $this->largethumb;
+ break;
+ default:
+ return '';
+ break;
+ }
+
+ if (!$thumb) {
+ return '';
+ }
+
+ $file = new ElggFile();
+ $file->owner_guid = $this->getOwnerGUID();
+ $file->setFilename($thumb);
+ return $file->grabFile();
+ }
+
+ public function getImage() {
+ return $this->grabFile();
+ }
+
+ /**
+ * Extract EXIF Data from image
+ *
+ * @warning image file must be saved first
+ */
+ public function extractExifData() {
+ elgg_load_library('tidypics:exif');
+ td_get_exif($this);
+ }
+
+ /**
+ * Has the photo been tagged with "in this photo" tags
+ *
+ * @return true/false
+ */
+ public function isPhotoTagged() {
+ $num_tags = count_annotations($this->getGUID(), 'object', 'image', 'phototag');
+ if ($num_tags > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get an array of photo tag information
+ *
+ * @return array
+ */
+ public function getPhotoTags() {
+
+ $tags = array();
+ $annotations = elgg_get_annotations(array(
+ 'guid' => $this->getGUID(),
+ 'annotation_name' => 'phototag',
+ ));
+ foreach ($annotations as $annotation) {
+ $tag = unserialize($annotation->value);
+ $tag->annotation_id = $annotation->id;
+ $tags[] = $tag;
+ }
+
+ return $tags;
+ }
+
+ /**
+ * Remove thumbnails - usually in preparation for deletion
+ *
+ * The thumbnails are not actually ElggObjects so we create
+ * temporary objects to delete them.
+ */
+ protected function removeThumbnails() {
+ $thumbnail = $this->thumbnail;
+ $smallthumb = $this->smallthumb;
+ $largethumb = $this->largethumb;
+
+ //delete standard thumbnail image
+ if ($thumbnail) {
+ $delfile = new ElggFile();
+ $delfile->owner_guid = $this->getOwnerGUID();
+ $delfile->setFilename($thumbnail);
+ $delfile->delete();
+ }
+ //delete small thumbnail image
+ if ($smallthumb) {
+ $delfile = new ElggFile();
+ $delfile->owner_guid = $this->getOwnerGUID();
+ $delfile->setFilename($smallthumb);
+ $delfile->delete();
+ }
+ //delete large thumbnail image
+ if ($largethumb) {
+ $delfile = new ElggFile();
+ $delfile->owner_guid = $this->getOwnerGUID();
+ $delfile->setFilename($largethumb);
+ $delfile->delete();
+ }
+ }
+}