END_OF_UPGRADE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function main()
{
if (Event::handle('StartUpgrade')) {
+ fixupConversationURIs();
+
updateSchemaCore();
updateSchemaPlugins();
// These replace old "fixup_*" scripts
- fixupNoticeRendered();
fixupNoticeConversation();
initConversation();
- initInbox();
fixupGroupURI();
+ fixupFileGeometry();
+ deleteLocalFileThumbnailsWithoutFilename();
+ deleteMissingLocalFileThumbnails();
+ setFilehashOnLocalFiles();
+ initGroupProfileId();
initLocalGroup();
initNoticeReshare();
- initFaveURI();
initSubscriptionURI();
initGroupMemberURI();
{
printfnq("Upgrading plugin schema...");
+ Event::handle('BeforePluginCheckSchema');
Event::handle('CheckSchema');
printfnq("DONE.\n");
}
-function fixupNoticeRendered()
-{
- printfnq("Ensuring all notices have rendered HTML...");
-
- $notice = new Notice();
-
- $notice->whereAdd('rendered IS NULL');
- $notice->find();
-
- while ($notice->fetch()) {
- $original = clone($notice);
- $notice->rendered = common_render_content($notice->content, $notice);
- $notice->update($original);
- }
-
- printfnq("DONE.\n");
-}
-
function fixupNoticeConversation()
{
printfnq("Ensuring all notices have a conversation ID...");
$notice = new Notice();
$notice->whereAdd('conversation is null');
+ $notice->whereAdd('conversation = 0', 'OR');
$notice->orderBy('id'); // try to get originals before replies
$notice->find();
$orig = clone($notice);
- if (empty($notice->reply_to)) {
- $notice->conversation = $notice->id;
- } else {
+ if (!empty($notice->reply_to)) {
$reply = Notice::getKV('id', $notice->reply_to);
- if (empty($reply)) {
- $notice->conversation = $notice->id;
- } else if (empty($reply->conversation)) {
- $notice->conversation = $notice->id;
- } else {
+ if ($reply instanceof Notice && !empty($reply->conversation)) {
$notice->conversation = $reply->conversation;
}
-
unset($reply);
- $reply = null;
+ }
+
+ // if still empty
+ if (empty($notice->conversation)) {
+ $child = new Notice();
+ $child->reply_to = $notice->getID();
+ $child->limit(1);
+ if ($child->find(true) && !empty($child->conversation)) {
+ $notice->conversation = $child->conversation;
+ }
+ unset($child);
+ }
+
+ // if _still_ empty we just create our own conversation
+ if (empty($notice->conversation)) {
+ $notice->conversation = $notice->getID();
}
$result = $notice->update($orig);
- $orig = null;
unset($orig);
} catch (Exception $e) {
- printv("Error setting conversation: " . $e->getMessage());
+ print("Error setting conversation: " . $e->getMessage());
}
}
printfnq("DONE.\n");
}
-function initInbox()
+function fixupConversationURIs()
{
- printfnq("Ensuring all users have an inbox...");
-
- $user = new User();
- $user->whereAdd('not exists (select user_id from inbox where user_id = user.id)');
- $user->orderBy('id');
-
- if ($user->find()) {
-
- while ($user->fetch()) {
-
- try {
- $notice = new Notice();
-
- $notice->selectAdd();
- $notice->selectAdd('id');
- $notice->joinAdd(array('profile_id', 'subscription:subscribed'));
- $notice->whereAdd('subscription.subscriber = ' . $user->id);
- $notice->whereAdd('notice.created >= subscription.created');
+ printfnq("Ensuring all conversations have a URI...");
+
+ $conv = new Conversation();
+ $conv->whereAdd('uri IS NULL');
+
+ if ($conv->find()) {
+ $rounds = 0;
+ while ($conv->fetch()) {
+ $uri = common_local_url('conversation', array('id' => $conv->id));
+ $sql = sprintf('UPDATE conversation SET uri="%1$s" WHERE id="%2$d";',
+ $conv->escape($uri), $conv->id);
+ $conv->query($sql);
+ if (($conv->N-++$rounds) % 500 == 0) {
+ printfnq(sprintf(' %d items left...', $conv->N-$rounds));
+ }
+ }
+ }
- $ids = array();
+ printfnq("DONE.\n");
+}
- if ($notice->find()) {
- while ($notice->fetch()) {
- $ids[] = $notice->id;
- }
- }
+function initGroupProfileId()
+{
+ printfnq("Ensuring all User_group entries have a Profile and profile_id...");
- $notice = null;
+ $group = new User_group();
+ $group->whereAdd('NOT EXISTS (SELECT id FROM profile WHERE id = user_group.profile_id)');
+ $group->find();
- $inbox = new Inbox();
- $inbox->user_id = $user->id;
- $inbox->pack($ids);
- $inbox->insert();
- } catch (Exception $e) {
- printv("Error initializing inbox: " . $e->getMessage());
+ while ($group->fetch()) {
+ try {
+ // We must create a new, incrementally assigned profile_id
+ $profile = new Profile();
+ $profile->nickname = $group->nickname;
+ $profile->fullname = $group->fullname;
+ $profile->profileurl = $group->mainpage;
+ $profile->homepage = $group->homepage;
+ $profile->bio = $group->description;
+ $profile->location = $group->location;
+ $profile->created = $group->created;
+ $profile->modified = $group->modified;
+
+ $profile->query('BEGIN');
+ $id = $profile->insert();
+ if (empty($id)) {
+ $profile->query('ROLLBACK');
+ throw new Exception('Profile insertion failed, profileurl: '.$profile->profileurl);
}
+ $group->query("UPDATE user_group SET profile_id={$id} WHERE id={$group->id}");
+ $profile->query('COMMIT');
+
+ $profile->free();
+ } catch (Exception $e) {
+ printfv("Error initializing Profile for group {$group->nickname}:" . $e->getMessage());
}
}
printfnq("DONE.\n");
}
-function initFaveURI()
-{
- printfnq("Ensuring all faves have a URI...");
-
- $fave = new Fave();
- $fave->whereAdd('uri IS NULL');
-
- if ($fave->find()) {
- while ($fave->fetch()) {
- try {
- $fave->decache();
- $fave->query(sprintf('update fave '.
- 'set uri = "%s", '.
- ' modified = "%s" '.
- 'where user_id = %d '.
- 'and notice_id = %d',
- Fave::newURI($fave->user_id, $fave->notice_id, $fave->modified),
- common_sql_date(strtotime($fave->modified)),
- $fave->user_id,
- $fave->notice_id));
- } catch (Exception $e) {
- common_log(LOG_ERR, "Error updated fave URI: " . $e->getMessage());
- }
- }
- }
-
- printfnq("DONE.\n");
-}
-
function initSubscriptionURI()
{
printfnq("Ensuring all subscriptions have a URI...");
'set uri = "%s" '.
'where subscriber = %d '.
'and subscribed = %d',
- Subscription::newURI($sub->subscriber, $sub->subscribed, $sub->created),
+ $sub->escape(Subscription::newUri($sub->getSubscriber(), $sub->getSubscribed(), $sub->created)),
$sub->subscriber,
$sub->subscribed));
} catch (Exception $e) {
$mem->query(sprintf('update group_member set uri = "%s" '.
'where profile_id = %d ' .
'and group_id = %d ',
- Group_member::newURI($mem->profile_id, $mem->group_id, $mem->created),
+ Group_member::newUri(Profile::getByID($mem->profile_id), User_group::getByID($mem->group_id), $mem->created),
$mem->profile_id,
$mem->group_id));
} catch (Exception $e) {
printfnq("DONE.\n");
}
+/*
+ * Added as we now store interpretd width and height in File table.
+ */
+function fixupFileGeometry()
+{
+ printfnq("Ensuring width and height is set for supported local File objects...");
+
+ $file = new File();
+ $file->whereAdd('filename IS NOT NULL'); // local files
+ $file->whereAdd('width IS NULL OR width = 0');
+
+ if ($file->find()) {
+ while ($file->fetch()) {
+ // Set file geometrical properties if available
+ try {
+ $image = ImageFile::fromFileObject($file);
+ } catch (ServerException $e) {
+ // We couldn't make out an image from the file.
+ continue;
+ }
+ $orig = clone($file);
+ $file->width = $image->width;
+ $file->height = $image->height;
+ $file->update($orig);
+
+ // FIXME: Do this more automagically inside ImageFile or so.
+ if ($image->getPath() != $file->getPath()) {
+ $image->unlink();
+ }
+ unset($image);
+ }
+ }
+
+ printfnq("DONE.\n");
+}
+
+/*
+ * File_thumbnail objects for local Files store their own filenames in the database.
+ */
+function deleteLocalFileThumbnailsWithoutFilename()
+{
+ printfnq("Removing all local File_thumbnail entries without filename property...");
+
+ $file = new File();
+ $file->whereAdd('filename IS NOT NULL'); // local files
+
+ if ($file->find()) {
+ // Looping through local File entries
+ while ($file->fetch()) {
+ $thumbs = new File_thumbnail();
+ $thumbs->file_id = $file->id;
+ $thumbs->whereAdd('filename IS NULL');
+ // Checking if there were any File_thumbnail entries without filename
+ if (!$thumbs->find()) {
+ continue;
+ }
+ // deleting incomplete entry to allow regeneration
+ while ($thumbs->fetch()) {
+ $thumbs->delete();
+ }
+ }
+ }
+
+ printfnq("DONE.\n");
+}
+
+/*
+ * Delete File_thumbnail entries where the referenced file does not exist.
+ */
+function deleteMissingLocalFileThumbnails()
+{
+ printfnq("Removing all local File_thumbnail entries without existing files...");
+
+ $thumbs = new File_thumbnail();
+ $thumbs->whereAdd('filename IS NOT NULL'); // only fill in names where they're missing
+ // Checking if there were any File_thumbnail entries without filename
+ if ($thumbs->find()) {
+ while ($thumbs->fetch()) {
+ try {
+ $thumbs->getPath();
+ } catch (FileNotFoundException $e) {
+ $thumbs->delete();
+ }
+ }
+ }
+
+ printfnq("DONE.\n");
+}
+
+/*
+ * Files are now stored with their hash, so let's generate for previously uploaded files.
+ */
+function setFilehashOnLocalFiles()
+{
+ printfnq('Ensuring all local files have the filehash field set...');
+
+ $file = new File();
+ $file->whereAdd('filename IS NOT NULL'); // local files
+ $file->whereAdd('filehash IS NULL', 'AND'); // without filehash value
+
+ if ($file->find()) {
+ while ($file->fetch()) {
+ try {
+ $orig = clone($file);
+ $file->filehash = hash_file(File::FILEHASH_ALG, $file->getPath());
+ $file->update($orig);
+ } catch (FileNotFoundException $e) {
+ echo "\n WARNING: file ID {$file->id} does not exist on path '{$e->path}'. If there is no file system error, run: php scripts/clean_file_table.php";
+ }
+ }
+ }
+
+ printfnq("DONE.\n");
+}
+
main();