]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Added functions help migrate images from Elgg's default file store to Tidypics.
authorBrett Profitt <brett.profitt@gmail.com>
Sun, 20 Sep 2009 02:20:05 +0000 (02:20 +0000)
committerBrett Profitt <brett.profitt@gmail.com>
Sun, 20 Sep 2009 02:20:05 +0000 (02:20 +0000)
lib/migrate.php [new file with mode: 0644]

diff --git a/lib/migrate.php b/lib/migrate.php
new file mode 100644 (file)
index 0000000..43a003a
--- /dev/null
@@ -0,0 +1,291 @@
+<?php
+
+// 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;
+
+       // 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);
+}