diff options
Diffstat (limited to 'mod/lightpics/lib/migrate.php')
| -rw-r--r-- | mod/lightpics/lib/migrate.php | 301 | 
1 files changed, 301 insertions, 0 deletions
| diff --git a/mod/lightpics/lib/migrate.php b/mod/lightpics/lib/migrate.php new file mode 100644 index 000000000..8c62126f0 --- /dev/null +++ b/mod/lightpics/lib/migrate.php @@ -0,0 +1,301 @@ +<?php +/** + * Tidypics file plugin migration + * + * Supports moving photos from the files plugin to Tidypics. All of a users + * photos end up in a single album. + * + * Not supported + */ + +// need access to ElggDiskFilestore::make_file_matrix(), which is protected. +// this is a PITA. +class tempFilestore extends ElggDiskFilestore { +	public function make_file_matrix($filename) { +		return parent::make_file_matrix($filename); +	} + +} +$filestore = new tempFilestore(); + + + +/** + * Migrates all pics from files to tidypics. + * + */ +function tidypics_migrate_pics() { +	$limit = 100; +	$r = true; + +	// migrate +	// @todo: should this return false since there was no error? +	if (!$users = tidypics_get_user_guids_with_pics_in_files(0, $limit)) { +		return $r; +	} + +	//echo "Grabbed " . count($users) . " users\n"; +	while (is_array($users) AND count($users) > 0) { +		foreach ($users as $user_guid) { +			// reset the query cache. +			$DB_QUERY_CACHE = array(); +			if (!$user = get_entity($user_guid)) { +				continue; +			} + +			$r = tidypics_migrate_user_pics($user); +		} + +		//echo "Trying to grab $limit more users...\n"; +		$offset = $offset + $limit; +		$users = tidypics_get_user_guids_with_pics_in_files($offset, $limit); +	} + +	return $r; +} + + +/** + * Migrates all pictures owned by a user regardless of + * if they're group or user files. + *  + * @param ElggUser $user User to migrate. + * @return bool on success + */ +function tidypics_migrate_user_pics(ElggUser $user) { +	global $CONFIG, $filestore; + +	$user_guid = $user->getGUID(); + +	// update all entity subtypes in a single go at the end. +	$updated_guids = array(); + +	if (!$pics = tidypics_get_user_pics_from_files($user_guid) OR count($pics) < 1) { +		return false; +	} + +	//echo "{$user->name} ({$user->getGUID()}) has " . count($pics) . " pics.\n"; +	 +	// get an album to migrate into if it already exists. +	// will create later on if it doesn't. +	$user_album_entities = get_entities_from_metadata('migrated_from_files', true, 'object', 'album', $user->getGUID(), 1); +	$user_album_guid = isset($album_entities[0]) ? $album_entities[0]->getGUID() : false; + +	// a list of albums to randomly select a cover for on newly created albums. +	$new_album_guids = array(); + +	foreach ($pics as $pic) { +		// check that it's not already in tidy pics +		if (false !== strpos($pic->filename, 'image/')) { +			//echo "{$pic->filename} ({$pic->getGUID()}) looks like it's already in tidy pics. Ignoring.\n"; +			continue; +		} +	 +		// blank some vars +		$group_pic = $group_album_guid = $group_guid = false; +		 +		// see if we're doing a group file migration. +		if ($pic->container_guid != $user->getGUID()  +			AND $group = get_entity($pic->container_guid) +			AND $group instanceof ElggGroup +		) { +			//echo "{$pic->getGUID()} is in a group!\n"; +			$group_pic = true; +			$group_guid = $group->getGUID(); +			 +			// yes, this is how you get entities by container_guid. +			// yes, it's wrong, wrong, wrong for this function to work this way. +			$group_album_entities = get_entities('object', 'album', $group_guid); +			 +			// get_entities_from_metadata doesn't support container_guid (or owner_guid meaning container_guid) +			// do it the hard way. +			if (is_array($group_album_entities)) { +				foreach ($group_album_entities as $group_album) { +					if ($group_album->migrated_from_files == true) { +						$group_album_guid = $group_album->getGUID(); +						break; +					} +				} +			} +			$album_guid = $group_album_guid; +			$group_album_guids[] = $group_album_guid; +		} else { +			$album_guid = $user_album_guid; +		} +		 +		//echo "album_guid is $album_guid and group_pic is: $group_pic\n"; +		 +		// create an album if we need to. +		if (!$album_guid) { +			//echo "Creating new album...\n"; +			$album = new ElggObject(); +			$album->subtype = 'album'; +			$album->new_album = TP_NEW_ALBUM; +			 +			if ($group_pic) { +				$album->container_guid = $group_guid; +				$album->owner_guid = $group->owner_guid; +				$album->access_id = $group->group_acl; +				$album->title = $group->name; +			} else { +				$album->container_guid = $user_guid; +				$album->owner_guid = $user->getGUID(); +				$album->access_id = ACCESS_DEFAULT; +				$album->title = $user->name; +			} + +			if (!$album->save()) { +				//echo "Couldn't migrate pics for {$user->name} ($user_guid)!\n"; +				return false; +			} +			$album->migrated_from_files = true; +			$album_guid = $album->getGUID(); +			$new_album_guids[] = $album_guid; +			 +			// save the album guid as the users +			if (!$group_pic) { +				$user_album_guid = $album_guid; +			} +		} +		 +		if (!tidypics_migrate_pic_from_files($pic, $album_guid)) { +			//echo "{$pic->filename} ({$pic->getGUID()}) Couldn't be migrated. Ignoring.\n"; +			continue; +		} +	} + +	// randomly pic an image to be the cover for the user gallery +	//$album->cover = $pic_guids[array_rand($pic_guids)]; +	foreach ($new_album_guids as $guid) { +		tidypics_set_random_cover_pic($guid); +	} +	 +	return true; +} + + +/** + * Randomly pics an image from an album to be the cover. + * @return bool on success + */ +function tidypics_set_random_cover_pic($album_guid) { +	global $CONFIG; +	 +	if ($album = get_entity($album_guid) AND $album instanceof TidypicsAlbum) { +		$q = "SELECT guid FROM {$CONFIG->dbprefix}entities WHERE container_guid = $album_guid ORDER BY RAND() limit 1"; +		$pic = get_data($q); +		 +		return $album->cover = $pic[0]->guid; +	} +	 +	return false; +} + +/** + * Migrates a single pic from the file repo. + * @return bool on succes. + */ +function tidypics_migrate_pic_from_files($pic, $album_guid) { +	global $CONFIG, $filestore; + +	// get the subtype id. +	$image_subtype_id = get_subtype_id('object', 'image'); + +	// hold which metadata on the files need to be changes +	// also holds the images we need to move +	$file_md_fields = array('filename', 'thumbnail', 'smallthumb', 'largethumb'); + +	if (!$user = get_entity($pic->owner_guid)) { +		return false; +	} + +	// figure out where to move the files. +	$matrix = $filestore->make_file_matrix($user->username); +	$user_fs_path = $CONFIG->dataroot . $matrix; +	$album_fs_path = $CONFIG->dataroot . $matrix . "image/$album_guid/"; +	if (!is_dir($album_fs_path)) { +		if (!mkdir($album_fs_path, 0700, true)) { +			return false; +		} +	} + +	// change all the 'file/'s to 'image/'s in certain metadata +	// these are also the files we need to move. +	foreach ($file_md_fields as $md_name) { +		// $pic->$md_name = str_replace('file/', 'image/', $pic->$md_name); +		$old_file = $pic->$md_name; +		$new_file = str_replace('file/', "image/$album_guid", $old_file); + +		if (!($old_fp = fopen($user_fs_path . $old_file, 'r')  +		AND $new_fp = fopen($user_fs_path . $new_file, 'w'))) { +			//echo "Could not move {$user_fs_path}{$old_file} to {$user_fs_path}{$new_file}\n"; +			continue; +		} + +		while (!feof($old_fp)) { +			if (!fputs($new_fp, fread($old_fp, 8192))) { +				//echo "Could not move {$user_fs_path}{$old_file} to {$user_fs_path}{$new_file} (Error writing.)\n"; +				break; +			} +		} + +		$pic->$md_name = $new_file; +	} +	// update container. +	// this doesn't work...? +	//$pic->container_guid = $album_guid; + +	// delete old one. +	unlink($user_fs_path . $old_file); + +	$q = "UPDATE {$CONFIG->dbprefix}entities SET subtype = $image_subtype_id, container_guid = $album_guid WHERE guid = {$pic->getGUID()}"; +	//echo "Finished moving {$user_fs_path}{$old_file} to {$user_fs_path}{$new_file}\n"; + +	return update_data($q); +} + + +/** + * Grabs all user IDs with images in the files repo. + * return mixed. False on fail, array of GUIDs on success. + */ +function tidypics_get_user_guids_with_pics_in_files($offset, $limit) { +	global $CONFIG; +	 +	//$simpletype_ms_id = add_metastring('simple_type'); +	//$image_ms_id = add_metastring('image'); +	 +	$q = "SELECT DISTINCT e.owner_guid  +		FROM  +			{$CONFIG->dbprefix}entities as e,  +			{$CONFIG->dbprefix}entity_subtypes as st +			 +		WHERE st.subtype = 'file' +		AND e.subtype = st.id +		LIMIT $offset, $limit"; + +	if (!$data = get_data($q)) { +		return false; +	} +	 +	// return an array of IDs +	$r = array(); +	foreach ($data as $row) { +		$r[] = $row->owner_guid; +	} + +	return $r; +} + +/** + * Gets a list of images for a single user. + * @return array of GUIDs, false on fail. + */ +function tidypics_get_user_pics_from_files($user_guid) { +	if (!$user = get_entity($user_guid) AND $user instanceof ElggUser) { +		return false; +	} + +	// @todo Might have to cycle this through with standard while + foreach. +	return get_entities_from_metadata('simpletype', 'image', 'object', 'file', $user_guid, 5000); +} | 
