]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - scripts/upgrade.php
Make sure reshare notices get the right object_type and verb
[quix0rs-gnu-social.git] / scripts / upgrade.php
1 #!/usr/bin/env php
2 <?php
3 /*
4  * StatusNet - a distributed open-source microblogging tool
5  * Copyright (C) 2008-2011 StatusNet, Inc.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
22
23 $shortoptions = 'x::';
24 $longoptions = array('extensions=');
25
26 $helptext = <<<END_OF_UPGRADE_HELP
27 php upgrade.php [options]
28 Upgrade database schema and data to latest software
29
30 END_OF_UPGRADE_HELP;
31
32 require_once INSTALLDIR.'/scripts/commandline.inc';
33
34 function main()
35 {
36     updateSchemaCore();
37     updateSchemaPlugins();
38
39     // These replace old "fixup_*" scripts
40
41     fixupNoticeRendered();
42     fixupNoticeConversation();
43     initConversation();
44     initInbox();
45     fixupGroupURI();
46     initLocalGroup();
47     initNoticeReshare();
48 }
49
50 function tableDefs()
51 {
52         $schema = array();
53         require INSTALLDIR.'/db/core.php';
54         return $schema;
55 }
56
57 function updateSchemaCore()
58 {
59     printfnq("Upgrading core schema...");
60
61     $schema = Schema::get();
62     $schemaUpdater = new SchemaUpdater($schema);
63     foreach (tableDefs() as $table => $def) {
64         $schemaUpdater->register($table, $def);
65     }
66     $schemaUpdater->checkSchema();
67
68     printfnq("DONE.\n");
69 }
70
71 function updateSchemaPlugins()
72 {
73     printfnq("Upgrading plugin schema...");
74
75     Event::handle('CheckSchema');
76
77     printfnq("DONE.\n");
78 }
79
80 function fixupNoticeRendered()
81 {
82     printfnq("Ensuring all notices have rendered HTML...");
83
84     $notice = new Notice();
85
86     $notice->whereAdd('rendered IS NULL');
87     $notice->find();
88
89     while ($notice->fetch()) {
90         $original = clone($notice);
91         $notice->rendered = common_render_content($notice->content, $notice);
92         $notice->update($original);
93     }
94
95     printfnq("DONE.\n");
96 }
97
98 function fixupNoticeConversation()
99 {
100     printfnq("Ensuring all notices have a conversation ID...");
101
102     $notice = new Notice();
103     $notice->whereAdd('conversation is null');
104     $notice->orderBy('id'); // try to get originals before replies
105     $notice->find();
106
107     while ($notice->fetch()) {
108         try {
109             $cid = null;
110     
111             $orig = clone($notice);
112     
113             if (empty($notice->reply_to)) {
114                 $notice->conversation = $notice->id;
115             } else {
116                 $reply = Notice::staticGet('id', $notice->reply_to);
117
118                 if (empty($reply)) {
119                     $notice->conversation = $notice->id;
120                 } else if (empty($reply->conversation)) {
121                     $notice->conversation = $notice->id;
122                 } else {
123                     $notice->conversation = $reply->conversation;
124                 }
125         
126                 unset($reply);
127                 $reply = null;
128             }
129
130             $result = $notice->update($orig);
131
132             $orig = null;
133             unset($orig);
134         } catch (Exception $e) {
135             printv("Error setting conversation: " . $e->getMessage());
136         }
137     }
138
139     printfnq("DONE.\n");
140 }
141
142 function fixupGroupURI()
143 {
144     printfnq("Ensuring all groups have an URI...");
145
146     $group = new User_group();
147     $group->whereAdd('uri IS NULL');
148
149     if ($group->find()) {
150         while ($group->fetch()) {
151             $orig = User_group::staticGet('id', $group->id);
152             $group->uri = $group->getUri();
153             $group->update($orig);
154         }
155     }
156
157     printfnq("DONE.\n");
158 }
159
160 function initConversation()
161 {
162     printfnq("Ensuring all conversations have a row in conversation table...");
163
164     $notice = new Notice();
165     $notice->query('select distinct notice.conversation from notice '.
166                    'where notice.conversation is not null '.
167                    'and not exists (select conversation.id from conversation where id = notice.conversation)');
168
169     while ($notice->fetch()) {
170
171         $id = $notice->conversation;
172
173         $uri = common_local_url('conversation', array('id' => $id));
174
175         // @fixme db_dataobject won't save our value for an autoincrement
176         // so we're bypassing the insert wrappers
177         $conv = new Conversation();
178         $sql = "insert into conversation (id,uri,created) values(%d,'%s','%s')";
179         $sql = sprintf($sql,
180                        $id,
181                        $conv->escape($uri),
182                        $conv->escape(common_sql_now()));
183         $conv->query($sql);
184     }
185
186     printfnq("DONE.\n");
187 }
188
189 function initInbox()
190 {
191     printfnq("Ensuring all users have an inbox...");
192
193     $user = new User();
194     $user->whereAdd('not exists (select user_id from inbox where user_id = user.id)');
195     $user->orderBy('id');
196
197     if ($user->find()) {
198
199         while ($user->fetch()) {
200
201             try {
202                 $notice = new Notice();
203
204                 $notice->selectAdd();
205                 $notice->selectAdd('id');
206                 $notice->joinAdd(array('profile_id', 'subscription:subscribed'));
207                 $notice->whereAdd('subscription.subscriber = ' . $user->id);
208                 $notice->whereAdd('notice.created >= subscription.created');
209
210                 $ids = array();
211
212                 if ($notice->find()) {
213                     while ($notice->fetch()) {
214                         $ids[] = $notice->id;
215                     }
216                 }
217
218                 $notice = null;
219
220                 $inbox = new Inbox();
221                 $inbox->user_id = $user->id;
222                 $inbox->pack($ids);
223                 $inbox->insert();
224             } catch (Exception $e) {
225                 printv("Error initializing inbox: " . $e->getMessage());
226             }
227         }
228     }
229
230     printfnq("DONE.\n");
231 }
232
233 function initLocalGroup()
234 {
235     printfnq("Ensuring all local user groups have a local_group...");
236
237     $group = new User_group();
238     $group->whereAdd('NOT EXISTS (select group_id from local_group where group_id = user_group.id)');
239     $group->find();
240
241     while ($group->fetch()) {
242         try {
243             // Hack to check for local groups
244             if ($group->getUri() == common_local_url('groupbyid', array('id' => $group->id))) {
245                 $lg = new Local_group();
246
247                 $lg->group_id = $group->id;
248                 $lg->nickname = $group->nickname;
249                 $lg->created  = $group->created; // XXX: common_sql_now() ?
250                 $lg->modified = $group->modified;
251
252                 $lg->insert();
253             }
254         } catch (Exception $e) {
255             printfv("Error initializing local group for {$group->nickname}:" . $e->getMessage());
256         }
257     }
258
259     printfnq("DONE.\n");
260 }
261
262 function initNoticeReshare()
263 {
264     printfnq("Ensuring all reshares have the correct verb and object-type...");
265     
266     $notice = new Notice();
267     $notice->whereAdd('repeat_of is not null');
268     $notice->whereAdd('(verb != "'.ActivityVerb::SHARE.'" OR object_type != "'.ActivityObject::ACTIVITY.'")');
269
270     if ($notice->find()) {
271         while ($notice->fetch()) {
272             try {
273                 $orig = Notice::staticGet('id', $notice->id);
274                 $notice->verb = ActivityVerb::SHARE;
275                 $notice->object_type = ActivityObject::ACTIVITY;
276                 $notice->update($orig);
277             } catch (Exception $e) {
278                 printfv("Error updating verb and object_type for {$notice->id}:" . $e->getMessage());
279             }
280         }
281     }
282
283     printfnq("DONE.\n");
284 }
285
286 main();