diff options
Diffstat (limited to 'mod/lightpics/classes')
| -rw-r--r-- | mod/lightpics/classes/TidypicsAlbum.php | 375 | ||||
| -rw-r--r-- | mod/lightpics/classes/TidypicsImage.php | 406 | 
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(); +		} +	} +} | 
