1<?php
2/**
3 * MyBB 1.8
4 * Copyright 2014 MyBB Group, All Rights Reserved
5 *
6 * Website: http://www.mybb.com
7 * License: http://www.mybb.com/about/license
8 *
9 */
10
11/**
12 * Upgrade Script: 1.6.14, 1.6.15, 1.6.16, 1.6.17 or 1.6.18
13 */
14
15$upgrade_detail = array(
16	"revert_all_templates" => 0,
17	"revert_all_themes" => 0,
18	"revert_all_settings" => 0
19);
20
21@set_time_limit(0);
22
23function upgrade30_dbchanges()
24{
25	global $cache, $output, $mybb, $db;
26
27	$output->print_header("Updating Database");
28
29	echo "<p>Performing necessary upgrade queries...</p>";
30	flush();
31
32	$db->update_query('settings', array('value' => -1), 'name IN (\'postmergefignore\', \'postmergeuignore\') AND value=\'\'');
33	$db->update_query('settings', array('optionscode' => 'forumselect'), 'name IN (\'postmergefignore\', \'portal_announcementsfid\') AND optionscode=\'text\'');
34	$db->update_query('settings', array('optionscode' => 'groupselect'), 'name=\'postmergeuignore\' AND optionscode=\'text\'');
35
36	if($db->type == "mysql" || $db->type == "mysqli")
37	{
38		if($db->index_exists('posts', 'tiddate'))
39		{
40			$db->drop_index('posts', 'tiddate');
41		}
42
43		$db->write_query("ALTER TABLE ".TABLE_PREFIX."posts ADD INDEX (`tid`, `dateline`)");
44	}
45
46	if($db->field_exists('modposts', 'usergroups'))
47	{
48		$db->drop_column("usergroups", "modposts");
49	}
50
51	if($db->field_exists('modthreads', 'usergroups'))
52	{
53		$db->drop_column("usergroups", "modthreads");
54	}
55
56	if($db->field_exists('mod_edit_posts', 'usergroups'))
57	{
58		$db->drop_column("usergroups", "mod_edit_posts");
59	}
60
61	if($db->field_exists('modattachments', 'usergroups'))
62	{
63		$db->drop_column("usergroups", "modattachments");
64	}
65
66	if($db->field_exists('regex', 'profilefields'))
67	{
68		$db->drop_column("profilefields", "regex");
69	}
70
71	if($db->field_exists('allowhtml', 'profilefields'))
72	{
73		$db->drop_column("profilefields", "allowhtml");
74	}
75
76	if($db->field_exists('allowmycode', 'profilefields'))
77	{
78		$db->drop_column("profilefields", "allowmycode");
79	}
80
81	if($db->field_exists('allowsmilies', 'profilefields'))
82	{
83		$db->drop_column("profilefields", "allowsmilies");
84	}
85
86	if($db->field_exists('allowimgcode', 'profilefields'))
87	{
88		$db->drop_column("profilefields", "allowimgcode");
89	}
90
91	if($db->field_exists('allowvideocode', 'profilefields'))
92	{
93		$db->drop_column("profilefields", "allowvideocode");
94	}
95
96	if($db->field_exists('viewableby', 'profilefields'))
97	{
98		$db->drop_column("profilefields", "viewableby");
99	}
100
101	if($db->field_exists('editable`', 'profilefields'))
102	{
103		$db->drop_column("profilefields", "editable");
104	}
105
106	if($db->field_exists('editableby', 'profilefields'))
107	{
108		$db->drop_column("profilefields", "editableby");
109	}
110
111	if($db->field_exists('oldgroup', 'awaitingactivation'))
112	{
113		$db->drop_column("awaitingactivation", "oldgroup");
114	}
115
116	if($db->field_exists('status', 'forums'))
117	{
118		$db->drop_column("forums", "status");
119	}
120
121	if($db->field_exists('posthash', 'posts'))
122	{
123		$db->drop_column("posts", "posthash");
124	}
125
126	if($db->field_exists('isdefault', 'templategroups'))
127	{
128		$db->drop_column("templategroups", "isdefault");
129	}
130
131	if($db->table_exists('reportedposts'))
132	{
133		if($db->field_exists('type', 'reportedposts'))
134		{
135			$db->drop_column("reportedposts", "type");
136		}
137
138		if($db->field_exists('reports', 'reportedposts'))
139		{
140			$db->drop_column("reportedposts", "reports");
141		}
142
143		if($db->field_exists('reporters', 'reportedposts'))
144		{
145			$db->drop_column("reportedposts", "reporters");
146		}
147
148		if($db->field_exists('lastreport', 'reportedposts'))
149		{
150			$db->drop_column("reportedposts", "lastreport");
151		}
152	}
153
154	if($db->field_exists('warnings', 'promotions'))
155	{
156		$db->drop_column("promotions", "warnings");
157	}
158
159	if($db->field_exists('warningstype', 'promotions'))
160	{
161		$db->drop_column("promotions", "warningstype");
162	}
163
164	if($db->field_exists('useragent', 'adminsessions'))
165	{
166		$db->drop_column("adminsessions", "useragent");
167	}
168
169	if($db->field_exists('deletedthreads', 'forums'))
170	{
171		$db->drop_column("forums", "deletedthreads");
172	}
173
174	if($db->field_exists('deletedposts', 'forums'))
175	{
176		$db->drop_column("forums", "deletedposts");
177	}
178
179	if($db->field_exists('threads', 'promotions'))
180	{
181		$db->drop_column('promotions', 'threads');
182	}
183
184	if($db->field_exists('threadtype', 'promotions'))
185	{
186		$db->drop_column('promotions', 'threadtype');
187	}
188
189	if($db->field_exists('online', 'promotions'))
190	{
191		$db->drop_column('promotions', 'online');
192	}
193
194	if($db->field_exists('onlinetype', 'promotions'))
195	{
196		$db->drop_column('promotions', 'onlinetype');
197	}
198
199	if($db->field_exists('modposts', 'forums'))
200	{
201		$db->drop_column("forums", "modposts");
202	}
203
204	if($db->field_exists('modthreads', 'forums'))
205	{
206		$db->drop_column("forums", "modthreads");
207	}
208
209	if($db->field_exists('mod_edit_posts', 'forums'))
210	{
211		$db->drop_column("forums", "mod_edit_posts");
212	}
213
214	if($db->field_exists('modattachments', 'forums'))
215	{
216		$db->drop_column("forums", "modattachments");
217	}
218
219	// Avoid complex convert coding...
220	if($db->field_exists('hidden', 'profilefields'))
221	{
222		$db->update_query('profilefields', array('hidden' => 2), 'hidden=1');
223		$db->update_query('profilefields', array('hidden' => 1), 'hidden=0');
224		$db->update_query('profilefields', array('hidden' => 0), 'hidden=2');
225
226		switch($db->type)
227		{
228			case "pgsql":
229				$db->rename_column("profilefields", "hidden", "profile", "smallint", "set", "'0'");
230				break;
231			default:
232				$db->rename_column("profilefields", "hidden", "profile", "tinyint(1) NOT NULL default '0'");
233				break;
234		}
235	}
236
237	switch($db->type)
238	{
239		case "pgsql":
240			$db->add_column("usergroups", "modposts", "smallint NOT NULL default '0' AFTER canratethreads");
241			$db->add_column("usergroups", "modthreads", "smallint NOT NULL default '0' AFTER modposts");
242			$db->add_column("usergroups", "mod_edit_posts", "smallint NOT NULL default '0' AFTER modthreads");
243			$db->add_column("usergroups", "modattachments", "smallint NOT NULL default '0' AFTER mod_edit_posts");
244			$db->add_column("profilefields", "regex", "text NOT NULL default ''");
245			$db->add_column("profilefields", "allowhtml", "smallint NOT NULL default '0'");
246			$db->add_column("profilefields", "allowmycode", "smallint NOT NULL default '0'");
247			$db->add_column("profilefields", "allowsmilies", "smallint NOT NULL default '0'");
248			$db->add_column("profilefields", "allowimgcode", "smallint NOT NULL default '0'");
249			$db->add_column("profilefields", "allowvideocode", "smallint NOT NULL default '0'");
250			$db->add_column("profilefields", "viewableby", "text NOT NULL default ''");
251			$db->add_column("profilefields", "editableby", "text NOT NULL default ''");
252			$db->add_column("templategroups", "isdefault", "smallint NOT NULL default '0'");
253			if($db->table_exists('reportedposts'))
254			{
255				$db->add_column("reportedposts", "type", "varchar(50) NOT NULL default ''");
256				$db->add_column("reportedposts", "reports", "int NOT NULL default '0'");
257				$db->add_column("reportedposts", "reporters", "text NOT NULL default ''");
258				$db->add_column("reportedposts", "lastreport", "bigint NOT NULL default '0'");
259			}
260			$db->add_column("promotions", "threads", "int NOT NULL default '0' AFTER posttype");
261			$db->add_column("promotions", "threadtype", "varchar(2) NOT NULL default '' AFTER threads");
262			$db->add_column("promotions", "warnings", "int NOT NULL default '0' AFTER referralstype");
263			$db->add_column("promotions", "warningstype", "varchar(2) NOT NULL default '' AFTER warnings");
264			$db->add_column("promotions", "online", "int NOT NULL default '0' AFTER warningstype");
265			$db->add_column("promotions", "onlinetype", "varchar(20) NOT NULL default '' AFTER online");
266			$db->add_column("adminsessions", "useragent", "varchar(100) NOT NULL default ''");
267			$db->add_column("forums", "deletedthreads", "int NOT NULL default '0' AFTER unapprovedposts");
268			$db->add_column("forums", "deletedposts", "int NOT NULL default '0' AFTER deletedthreads");
269			break;
270		case "sqlite":
271			$db->add_column("usergroups", "modposts", "tinyint(1) NOT NULL default '0' AFTER canratethreads");
272			$db->add_column("usergroups", "modthreads", "tinyint(1) NOT NULL default '0' AFTER modposts");
273			$db->add_column("usergroups", "mod_edit_posts", "tinyint(1) NOT NULL default '0' AFTER modthreads");
274			$db->add_column("usergroups", "modattachments", "tinyint(1) NOT NULL default '0' AFTER mod_edit_posts");
275			$db->add_column("profilefields", "regex", "text NOT NULL default ''");
276			$db->add_column("profilefields", "allowhtml", "tinyint(1) NOT NULL default '0'");
277			$db->add_column("profilefields", "allowmycode", "tinyint(1) NOT NULL default '0'");
278			$db->add_column("profilefields", "allowsmilies", "tinyint(1) NOT NULL default '0'");
279			$db->add_column("profilefields", "allowimgcode", "tinyint(1) NOT NULL default '0'");
280			$db->add_column("profilefields", "allowvideocode", "tinyint(1) NOT NULL default '0'");
281			$db->add_column("profilefields", "viewableby", "text NOT NULL default ''");
282			$db->add_column("profilefields", "editableby", "text NOT NULL default ''");
283			$db->add_column("templategroups", "isdefault", "tinyint(1) NOT NULL default '0'");
284			if($db->table_exists('reportedposts'))
285			{
286				$db->add_column("reportedposts", "type", "varchar(50) NOT NULL default ''");
287				$db->add_column("reportedposts", "reports", "int NOT NULL default '0'");
288				$db->add_column("reportedposts", "reporters", "text NOT NULL default ''");
289				$db->add_column("reportedposts", "lastreport", "bigint NOT NULL default '0'");
290			}
291			$db->add_column("promotions", "warnings", "int NOT NULL default '0' AFTER referralstype");
292			$db->add_column("promotions", "warningstype", "varchar(2) NOT NULL default '' AFTER warnings");
293			$db->add_column("adminsessions", "useragent", "varchar(100) NOT NULL default ''");
294			$db->add_column("forums", "deletedthreads", "int NOT NULL default '0' AFTER unapprovedposts");
295			$db->add_column("forums", "deletedposts", "int NOT NULL default '0' AFTER deletedthreads");
296			break;
297		default:
298			$db->add_column("usergroups", "modposts", "tinyint(1) NOT NULL default '0' AFTER canratethreads");
299			$db->add_column("usergroups", "modthreads", "tinyint(1) NOT NULL default '0' AFTER modposts");
300			$db->add_column("usergroups", "mod_edit_posts", "tinyint(1) NOT NULL default '0' AFTER modthreads");
301			$db->add_column("usergroups", "modattachments", "tinyint(1) NOT NULL default '0' AFTER mod_edit_posts");
302			$db->add_column("profilefields", "regex", "text NOT NULL");
303			$db->add_column("profilefields", "allowhtml", "tinyint(1) NOT NULL default '0'");
304			$db->add_column("profilefields", "allowmycode", "tinyint(1) NOT NULL default '0'");
305			$db->add_column("profilefields", "allowsmilies", "tinyint(1) NOT NULL default '0'");
306			$db->add_column("profilefields", "allowimgcode", "tinyint(1) NOT NULL default '0'");
307			$db->add_column("profilefields", "allowvideocode", "tinyint(1) NOT NULL default '0'");
308			$db->add_column("profilefields", "viewableby", "text NOT NULL");
309			$db->add_column("profilefields", "editableby", "text NOT NULL");
310			$db->add_column("templategroups", "isdefault", "tinyint(1) NOT NULL default '0'");
311			if($db->table_exists('reportedposts'))
312			{
313				$db->add_column("reportedposts", "type", "varchar(50) NOT NULL default ''");
314				$db->add_column("reportedposts", "reports", "int unsigned NOT NULL default '0'");
315				$db->add_column("reportedposts", "reporters", "text NOT NULL");
316				$db->add_column("reportedposts", "lastreport", "bigint(30) NOT NULL default '0'");
317			}
318			$db->add_column("promotions", "threads", "int NOT NULL default '0' AFTER posttype");
319			$db->add_column("promotions", "threadtype", "char(2) NOT NULL default '' AFTER threads");
320			$db->add_column("promotions", "warnings", "int NOT NULL default '0' AFTER referralstype");
321			$db->add_column("promotions", "warningstype", "char(2) NOT NULL default '' AFTER warnings");
322			$db->add_column("promotions", "online", "int NOT NULL default '0' AFTER warningstype");
323			$db->add_column("promotions", "onlinetype", "varchar(20) NOT NULL default '' AFTER online");
324			$db->add_column("adminsessions", "useragent", "varchar(100) NOT NULL default ''");
325			$db->add_column("forums", "deletedthreads", "int(10) NOT NULL default '0' AFTER unapprovedposts");
326			$db->add_column("forums", "deletedposts", "int(10) NOT NULL default '0' AFTER deletedthreads");
327			break;
328	}
329
330	$db->update_query('profilefields', array('viewableby' => '-1', 'editableby' => '-1'));
331
332	global $footer_extra;
333	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
334
335	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
336	$output->print_footer("30_dbchanges2");
337}
338
339function upgrade30_dbchanges2()
340{
341	global $cache, $output, $mybb, $db;
342
343	$output->print_header("Updating Database");
344
345	echo "<p>Performing necessary upgrade queries...</p>";
346	flush();
347
348	if($db->field_exists('ipaddress', 'privatemessages'))
349	{
350		$db->drop_column('privatemessages', 'ipaddress');
351	}
352
353	if($db->field_exists('canonlyreplyownthreads', 'forumpermissions'))
354	{
355		$db->drop_column("forumpermissions", "canonlyreplyownthreads");
356	}
357
358	if($db->field_exists('modposts', 'forumpermissions'))
359	{
360		$db->drop_column("forumpermissions", "modposts");
361	}
362
363	if($db->field_exists('modthreads', 'forumpermissions'))
364	{
365		$db->drop_column("forumpermissions", "modthreads");
366	}
367
368	if($db->field_exists('mod_edit_posts', 'forumpermissions'))
369	{
370		$db->drop_column("forumpermissions", "mod_edit_posts");
371	}
372
373	if($db->field_exists('modattachments', 'forumpermissions'))
374	{
375		$db->drop_column("forumpermissions", "modattachments");
376	}
377
378	if($db->field_exists('canbereported', 'usergroups'))
379	{
380		$db->drop_column('usergroups', 'canbereported');
381	}
382
383	if($db->field_exists('edittimelimit', 'usergroups'))
384	{
385		$db->drop_column("usergroups", "edittimelimit");
386	}
387
388	if($db->field_exists('maxposts', 'usergroups'))
389	{
390		$db->drop_column("usergroups", "maxposts");
391	}
392
393	if($db->field_exists('showmemberlist', 'usergroups'))
394	{
395		$db->drop_column("usergroups", "showmemberlist");
396	}
397
398	if($db->field_exists('canviewboardclosed', 'usergroups'))
399	{
400		$db->drop_column("usergroups", "canviewboardclosed");
401	}
402
403	if($db->field_exists('deletedposts', 'threads'))
404	{
405		$db->drop_column("threads", "deletedposts");
406	}
407
408	if($db->field_exists('used', 'captcha'))
409	{
410		$db->drop_column("captcha", "used");
411	}
412
413	if($db->field_exists('editreason', 'posts'))
414	{
415		$db->drop_column("posts", "editreason");
416	}
417
418	if($db->field_exists('usethreadcounts', 'forums'))
419	{
420		$db->drop_column("forums", "usethreadcounts");
421	}
422
423	if($db->field_exists('requireprefix', 'forums'))
424	{
425		$db->drop_column("forums", "requireprefix");
426	}
427
428	if($db->field_exists('threadnum', 'users'))
429	{
430		$db->drop_column("users", "threadnum");
431	}
432
433	if($db->field_exists('canchangewebsite', 'usergroups'))
434	{
435		$db->drop_column("usergroups", "canchangewebsite");
436	}
437
438	switch($db->type)
439	{
440		case "pgsql":
441			$db->add_column("forumpermissions", "canonlyreplyownthreads", "smallint NOT NULL default '0' AFTER canpostreplys");
442			$db->add_column("forumpermissions", "modposts", "smallint NOT NULL default '0' AFTER caneditattachments");
443			$db->add_column("forumpermissions", "modthreads", "smallint NOT NULL default '0' AFTER modposts");
444			$db->add_column("forumpermissions", "mod_edit_posts", "smallint NOT NULL default '0' AFTER modthreads");
445			$db->add_column("forumpermissions", "modattachments", "smallint NOT NULL default '0' AFTER mod_edit_posts");
446			$db->add_column("usergroups", "canbereported", "smallint NOT NULL default '0' AFTER canchangename");
447			$db->add_column("usergroups", "canchangewebsite", "smallint NOT NULL default '1' AFTER canbereported");
448			$db->add_column("usergroups", "edittimelimit", "int NOT NULL default '0'");
449			$db->add_column("usergroups", "maxposts", "int NOT NULL default '0'");
450			$db->add_column("usergroups", "showmemberlist", "smallint NOT NULL default '1'");
451			$db->add_column("usergroups", "canviewboardclosed", "smallint NOT NULL default '0' AFTER candlattachments");
452			$db->add_column("threads", "deletedposts", "int NOT NULL default '0' AFTER unapprovedposts");
453			$db->add_column("captcha", "used", "smallint NOT NULL default '0'");
454			$db->add_column("posts", "editreason", "varchar(150) NOT NULL default '' AFTER edittime");
455			$db->add_column("forums", "usethreadcounts", "smallint NOT NULL default '0' AFTER usepostcounts");
456			$db->add_column("forums", "requireprefix", "smallint NOT NULL default '0' AFTER usethreadcounts");
457			$db->add_column("users", "threadnum", "int NOT NULL default '0' AFTER postnum");
458			break;
459		default:
460			$db->add_column("forumpermissions", "canonlyreplyownthreads", "tinyint(1) NOT NULL default '0' AFTER canpostreplys");
461			$db->add_column("forumpermissions", "modposts", "tinyint(1) NOT NULL default '0' AFTER caneditattachments");
462			$db->add_column("forumpermissions", "modthreads", "tinyint(1) NOT NULL default '0' AFTER modposts");
463			$db->add_column("forumpermissions", "mod_edit_posts", "tinyint(1) NOT NULL default '0' AFTER modthreads");
464			$db->add_column("forumpermissions", "modattachments", "tinyint(1) NOT NULL default '0' AFTER mod_edit_posts");
465			$db->add_column("usergroups", "canbereported", "tinyint(1) NOT NULL default '0' AFTER canchangename");
466			$db->add_column("usergroups", "canchangewebsite", "tinyint(1) NOT NULL default '1' AFTER canbereported");
467			$db->add_column("usergroups", "edittimelimit", "int(4) NOT NULL default '0'");
468			$db->add_column("usergroups", "maxposts", "int(4) NOT NULL default '0'");
469			$db->add_column("usergroups", "showmemberlist", "tinyint(1) NOT NULL default '1'");
470			$db->add_column("usergroups", "canviewboardclosed", "tinyint(1) NOT NULL default '0' AFTER candlattachments");
471			$db->add_column("threads", "deletedposts", "int(10) NOT NULL default '0' AFTER unapprovedposts");
472			$db->add_column("captcha", "used", "tinyint(1) NOT NULL default '0'");
473			$db->add_column("posts", "editreason", "varchar(150) NOT NULL default '' AFTER edittime");
474			$db->add_column("forums", "usethreadcounts", "tinyint(1) NOT NULL default '0' AFTER usepostcounts");
475			$db->add_column("forums", "requireprefix", "tinyint(1) NOT NULL default '0' AFTER usethreadcounts");
476			$db->add_column("users", "threadnum", "int(10) NOT NULL default '0' AFTER postnum");
477			break;
478	}
479
480	$db->update_query('forums', array('usethreadcounts' => 1), 'usepostcounts = 1');
481
482	global $footer_extra;
483	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
484
485	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
486	$output->print_footer("30_dbchanges3");
487}
488
489function upgrade30_dbchanges3()
490{
491	global $cache, $output, $mybb, $db;
492
493	$output->print_header("Updating Database");
494
495	echo "<p>Performing necessary upgrade queries...</p>";
496	flush();
497
498	if($db->field_exists('cansoftdeleteposts', 'moderators'))
499	{
500		$db->drop_column('moderators', 'cansoftdeleteposts');
501	}
502
503	if($db->field_exists('canrestoreposts', 'moderators'))
504	{
505		$db->drop_column("moderators", "canrestoreposts");
506	}
507
508	if($db->field_exists('cansoftdeletethreads', 'moderators'))
509	{
510		$db->drop_column('moderators', 'cansoftdeletethreads');
511	}
512
513	if($db->field_exists('canrestorethreads', 'moderators'))
514	{
515		$db->drop_column("moderators", "canrestorethreads");
516	}
517
518	if($db->field_exists('candeletethreads', 'moderators'))
519	{
520		$db->drop_column("moderators", "candeletethreads");
521	}
522
523	if($db->field_exists('canviewunapprove', 'moderators'))
524	{
525		$db->drop_column("moderators", "canviewunapprove");
526	}
527
528	if($db->field_exists('canviewdeleted', 'moderators'))
529	{
530		$db->drop_column("moderators", "canviewdeleted");
531	}
532
533	if($db->field_exists('canstickunstickthreads', 'moderators'))
534	{
535		$db->drop_column("moderators", "canstickunstickthreads");
536	}
537
538	if($db->field_exists('canapproveunapprovethreads', 'moderators'))
539	{
540		$db->drop_column("moderators", "canapproveunapprovethreads");
541	}
542
543	if($db->field_exists('canapproveunapproveposts', 'moderators'))
544	{
545		$db->drop_column("moderators", "canapproveunapproveposts");
546	}
547
548	if($db->field_exists('canapproveunapproveattachs', 'moderators'))
549	{
550		$db->drop_column("moderators", "canapproveunapproveattachs");
551	}
552
553	if($db->field_exists('canmanagepolls', 'moderators'))
554	{
555		$db->drop_column("moderators", "canmanagepolls");
556	}
557
558	if($db->field_exists('canpostclosedthreads', 'moderators'))
559	{
560		$db->drop_column("moderators", "canpostclosedthreads");
561	}
562
563	if($db->field_exists('canmanageannouncements', 'moderators'))
564	{
565		$db->drop_column("moderators", "canmanageannouncements");
566	}
567
568	if($db->field_exists('canmanagereportedposts', 'moderators'))
569	{
570		$db->drop_column("moderators", "canmanagereportedposts");
571	}
572
573	if($db->field_exists('canviewmodlog', 'moderators'))
574	{
575		$db->drop_column("moderators", "canviewmodlog");
576	}
577
578	switch($db->type)
579	{
580		case "pgsql":
581			$db->add_column("moderators", "cansoftdeleteposts", "smallint NOT NULL default '0' AFTER caneditposts");
582			$db->add_column("moderators", "canrestoreposts", "smallint NOT NULL default '0' AFTER cansoftdeleteposts");
583			$db->add_column("moderators", "cansoftdeletethreads", "smallint NOT NULL default '0' AFTER candeleteposts");
584			$db->add_column("moderators", "canrestorethreads", "smallint NOT NULL default '0' AFTER cansoftdeletethreads");
585			$db->add_column("moderators", "candeletethreads", "smallint NOT NULL default '0' AFTER canrestorethreads");
586			$db->add_column("moderators", "canviewunapprove", "smallint NOT NULL default '0' AFTER canviewips");
587			$db->add_column("moderators", "canviewdeleted", "smallint NOT NULL default '0' AFTER canviewunapprove");
588			$db->add_column("moderators", "canstickunstickthreads", "smallint NOT NULL default '0' AFTER canopenclosethreads");
589			$db->add_column("moderators", "canapproveunapprovethreads", "smallint NOT NULL default '0' AFTER canstickunstickthreads");
590			$db->add_column("moderators", "canapproveunapproveposts", "smallint NOT NULL default '0' AFTER canapproveunapprovethreads");
591			$db->add_column("moderators", "canapproveunapproveattachs", "smallint NOT NULL default '0' AFTER canapproveunapproveposts");
592			$db->add_column("moderators", "canmanagepolls", "smallint NOT NULL default '0' AFTER canmanagethreads");
593			$db->add_column("moderators", "canpostclosedthreads", "smallint NOT NULL default '0' AFTER canmanagepolls");
594			$db->add_column("moderators", "canmanageannouncements", "smallint NOT NULL default '0' AFTER canusecustomtools");
595			$db->add_column("moderators", "canmanagereportedposts", "smallint NOT NULL default '0' AFTER canmanageannouncements");
596			$db->add_column("moderators", "canviewmodlog", "smallint NOT NULL default '0' AFTER canmanagereportedposts");
597			break;
598		default:
599			$db->add_column("moderators", "cansoftdeleteposts", "tinyint(1) NOT NULL default '0' AFTER caneditposts");
600			$db->add_column("moderators", "canrestoreposts", "tinyint(1) NOT NULL default '0' AFTER cansoftdeleteposts");
601			$db->add_column("moderators", "cansoftdeletethreads", "tinyint(1) NOT NULL default '0' AFTER candeleteposts");
602			$db->add_column("moderators", "canrestorethreads", "tinyint(1) NOT NULL default '0' AFTER cansoftdeletethreads");
603			$db->add_column("moderators", "candeletethreads", "tinyint(1) NOT NULL default '0' AFTER canrestorethreads");
604			$db->add_column("moderators", "canviewunapprove", "tinyint(1) NOT NULL default '0' AFTER canviewips");
605			$db->add_column("moderators", "canviewdeleted", "tinyint(1) NOT NULL default '0' AFTER canviewunapprove");
606			$db->add_column("moderators", "canstickunstickthreads", "tinyint(1) NOT NULL default '0' AFTER canopenclosethreads");
607			$db->add_column("moderators", "canapproveunapprovethreads", "tinyint(1) NOT NULL default '0' AFTER canstickunstickthreads");
608			$db->add_column("moderators", "canapproveunapproveposts", "tinyint(1) NOT NULL default '0' AFTER canapproveunapprovethreads");
609			$db->add_column("moderators", "canapproveunapproveattachs", "tinyint(1) NOT NULL default '0' AFTER canapproveunapproveposts");
610			$db->add_column("moderators", "canmanagepolls", "tinyint(1) NOT NULL default '0' AFTER canmanagethreads");
611			$db->add_column("moderators", "canpostclosedthreads", "tinyint(1) NOT NULL default '0' AFTER canmanagepolls");
612			$db->add_column("moderators", "canmanageannouncements", "tinyint(1) NOT NULL default '0' AFTER canusecustomtools");
613			$db->add_column("moderators", "canmanagereportedposts", "tinyint(1) NOT NULL default '0' AFTER canmanageannouncements");
614			$db->add_column("moderators", "canviewmodlog", "tinyint(1) NOT NULL default '0' AFTER canmanagereportedposts");
615			break;
616	}
617
618	global $footer_extra;
619	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
620
621	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
622	$output->print_footer("30_dbchanges4");
623}
624
625function upgrade30_dbchanges4()
626{
627	global $cache, $output, $mybb, $db;
628
629	$output->print_header("Updating Database");
630
631	echo "<p>Performing necessary upgrade queries...</p>";
632	flush();
633
634	if($db->field_exists('emailfloodtime', 'usergroups'))
635	{
636		$db->drop_column("usergroups", "emailfloodtime");
637	}
638
639	if($db->field_exists('canmanageannounce', 'usergroups'))
640	{
641		$db->drop_column("usergroups", "canmanageannounce");
642	}
643
644	if($db->field_exists('canmanagemodqueue', 'usergroups'))
645	{
646		$db->drop_column("usergroups", "canmanagemodqueue");
647	}
648
649	if($db->field_exists('canmanagereportedcontent', 'usergroups'))
650	{
651		$db->drop_column("usergroups", "canmanagereportedcontent");
652	}
653
654	if($db->field_exists('canviewmodlogs', 'usergroups'))
655	{
656		$db->drop_column("usergroups", "canviewmodlogs");
657	}
658
659	if($db->field_exists('caneditprofiles', 'usergroups'))
660	{
661		$db->drop_column("usergroups", "caneditprofiles");
662	}
663
664	if($db->field_exists('canbanusers', 'usergroups'))
665	{
666		$db->drop_column("usergroups", "canbanusers");
667	}
668
669	if($db->field_exists('canviewwarnlogs', 'usergroups'))
670	{
671		$db->drop_column("usergroups", "canviewwarnlogs");
672	}
673
674	if($db->field_exists('canuseipsearch', 'usergroups'))
675	{
676		$db->drop_column("usergroups", "canuseipsearch");
677	}
678
679	if($db->field_exists('type', 'maillogs'))
680	{
681		$db->drop_column("maillogs", "type");
682	}
683
684	if($db->field_exists('groups', 'modtools'))
685	{
686		$db->drop_column("modtools", "groups");
687	}
688
689	switch($db->type)
690	{
691		case "pgsql":
692			$db->add_column("usergroups", "emailfloodtime", "int NOT NULL default '5' AFTER maxemails");
693			$db->add_column("usergroups", "canmanageannounce", "smallint NOT NULL default '0' AFTER showmemberlist");
694			$db->add_column("usergroups", "canmanagemodqueue", "smallint NOT NULL default '0' AFTER canmanageannounce");
695			$db->add_column("usergroups", "canmanagereportedcontent", "smallint NOT NULL default '0' AFTER canmanagemodqueue");
696			$db->add_column("usergroups", "canviewmodlogs", "smallint NOT NULL default '0' AFTER canmanagereportedcontent");
697			$db->add_column("usergroups", "caneditprofiles", "smallint NOT NULL default '0' AFTER canviewmodlogs");
698			$db->add_column("usergroups", "canbanusers", "smallint NOT NULL default '0' AFTER caneditprofiles");
699			$db->add_column("usergroups", "canviewwarnlogs", "smallint NOT NULL default '0' AFTER canbanusers");
700			$db->add_column("usergroups", "canuseipsearch", "smallint NOT NULL default '0' AFTER canviewwarnlogs");
701			$db->add_column("maillogs", "type", "smallint NOT NULL default '0'");
702			break;
703		default:
704			$db->add_column("usergroups", "emailfloodtime", "int(3) NOT NULL default '5' AFTER maxemails");
705			$db->add_column("usergroups", "canmanageannounce", "tinyint(1) NOT NULL default '0' AFTER showmemberlist");
706			$db->add_column("usergroups", "canmanagemodqueue", "tinyint(1) NOT NULL default '0' AFTER canmanageannounce");
707			$db->add_column("usergroups", "canmanagereportedcontent", "tinyint(1) NOT NULL default '0' AFTER canmanagemodqueue");
708			$db->add_column("usergroups", "canviewmodlogs", "tinyint(1) NOT NULL default '0' AFTER canmanagereportedcontent");
709			$db->add_column("usergroups", "caneditprofiles", "tinyint(1) NOT NULL default '0' AFTER canviewmodlogs");
710			$db->add_column("usergroups", "canbanusers", "tinyint(1) NOT NULL default '0' AFTER caneditprofiles");
711			$db->add_column("usergroups", "canviewwarnlogs", "tinyint(1) NOT NULL default '0' AFTER canbanusers");
712			$db->add_column("usergroups", "canuseipsearch", "tinyint(1) NOT NULL default '0' AFTER canviewwarnlogs");
713			$db->add_column("maillogs", "type", "tinyint(1) NOT NULL default '0'");
714			break;
715	}
716
717	switch($db->type)
718	{
719		case "sqlite":
720			$db->add_column("modtools", "groups", "text NOT NULL default ''");
721			break;
722		default:
723			$db->add_column("modtools", "groups", "text NOT NULL");
724			break;
725	}
726
727	$update_array = array(
728		"canmanageannounce" => 1,
729		"canmanagemodqueue" => 1,
730		"canmanagereportedcontent" => 1,
731		"canviewmodlogs" => 1,
732		"caneditprofiles" => 1,
733		"canbanusers" => 1,
734		"canviewwarnlogs" => 1,
735		"canuseipsearch" => 1
736	);
737	$db->update_query("usergroups", $update_array, "canmodcp= '1'");
738
739	$update_array = array(
740		"type" => 1
741	);
742	$db->update_query("maillogs", $update_array, "tid= '0'");
743
744	$update_array = array(
745		"type" => 2
746	);
747	$db->update_query("maillogs", $update_array, "tid > '0'");
748
749	global $footer_extra;
750	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
751
752	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
753	$output->print_footer("30_dbchanges5");
754}
755
756function upgrade30_dbchanges5()
757{
758	global $cache, $output, $mybb, $db;
759
760	$output->print_header("Updating Database");
761
762	echo "<p>Performing necessary upgrade queries...</p>";
763	flush();
764
765	if($db->table_exists("questions"))
766	{
767		$db->drop_table("questions");
768	}
769
770	if($db->table_exists("questionsessions"))
771	{
772		$db->drop_table("questionsessions");
773	}
774
775	if($db->table_exists("spamlog"))
776	{
777		$db->drop_table("spamlog");
778	}
779
780	$collation = $db->build_create_table_collation();
781
782	switch($db->type)
783	{
784		case "sqlite":
785			$db->write_query("CREATE TABLE ".TABLE_PREFIX."questions (
786				qid INTEGER PRIMARY KEY,
787				question varchar(200) NOT NULL default '',
788				answer varchar(150) NOT NULL default '',
789				shown int unsigned NOT NULL default 0,
790				correct int unsigned NOT NULL default 0,
791				incorrect int unsigned NOT NULL default 0,
792				active tinyint(1) NOT NULL default '0'
793			);");
794			$db->write_query("CREATE TABLE ".TABLE_PREFIX."questionsessions (
795				sid varchar(32) NOT NULL default '',
796				qid int unsigned NOT NULL default '0',
797				dateline int unsigned NOT NULL default '0'
798			);");
799			$db->write_query("CREATE TABLE ".TABLE_PREFIX."spamlog (
800				sid INTEGER PRIMARY KEY,
801				username varchar(120) NOT NULL DEFAULT '',
802				email varchar(220) NOT NULL DEFAULT '',
803				ipaddress blob(16) NOT NULL default '',
804				dateline int unsigned NOT NULL default '0',
805				data TEXT NOT NULL
806			);");
807			break;
808		case "pgsql":
809			$db->write_query("CREATE TABLE ".TABLE_PREFIX."questions (
810				qid serial,
811				question varchar(200) NOT NULL default '',
812				answer varchar(150) NOT NULL default '',
813				shown int NOT NULL default 0,
814				correct int NOT NULL default 0,
815				incorrect int NOT NULL default 0,
816				active smallint NOT NULL default '0',
817				PRIMARY KEY (qid)
818			);");
819			$db->write_query("CREATE TABLE ".TABLE_PREFIX."questionsessions (
820				sid varchar(32) NOT NULL default '',
821				qid int NOT NULL default '0',
822				dateline int NOT NULL default '0',
823				UNIQUE (sid)
824			);");
825			$db->write_query("CREATE TABLE ".TABLE_PREFIX."spamlog (
826				sid serial,
827				username varchar(120) NOT NULL DEFAULT '',
828				email varchar(220) NOT NULL DEFAULT '',
829				ipaddress bytea NOT NULL default '',
830				dateline numeric(30,0) NOT NULL default '0',
831				data text NOT NULL default '',
832				PRIMARY KEY (sid)
833			);");
834			break;
835		default:
836			$db->write_query("CREATE TABLE ".TABLE_PREFIX."questions (
837				qid int unsigned NOT NULL auto_increment,
838				question varchar(200) NOT NULL default '',
839				answer varchar(150) NOT NULL default '',
840				shown int unsigned NOT NULL default 0,
841				correct int unsigned NOT NULL default 0,
842				incorrect int unsigned NOT NULL default 0,
843				active tinyint(1) NOT NULL default '0',
844				PRIMARY KEY (qid)
845			) ENGINE=MyISAM{$collation}");
846			$db->write_query("CREATE TABLE ".TABLE_PREFIX."questionsessions (
847				sid varchar(32) NOT NULL default '',
848				qid int unsigned NOT NULL default '0',
849				dateline int unsigned NOT NULL default '0',
850				PRIMARY KEY (sid)
851			) ENGINE=MyISAM{$collation}");
852			$db->write_query("CREATE TABLE ".TABLE_PREFIX."spamlog (
853				sid int unsigned NOT NULL auto_increment,
854				username varchar(120) NOT NULL DEFAULT '',
855				email varchar(220) NOT NULL DEFAULT '',
856				ipaddress varbinary(16) NOT NULL default '',
857				dateline int unsigned NOT NULL default '0',
858				data text NOT NULL,
859				PRIMARY KEY (sid)
860			) ENGINE=MyISAM{$collation}");
861	}
862
863	global $footer_extra;
864	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
865
866	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
867	$output->print_footer("30_dbchanges6");
868}
869
870function upgrade30_dbchanges6()
871{
872	global $cache, $output, $mybb, $db;
873
874	$output->print_header("Updating Database");
875
876	echo "<p>Performing necessary upgrade queries...</p>";
877	flush();
878
879	if($db->table_exists("buddyrequests"))
880	{
881		$db->drop_table("buddyrequests");
882	}
883
884	$collation = $db->build_create_table_collation();
885
886	switch($db->type)
887	{
888		case "pgsql":
889			$db->write_query("CREATE TABLE ".TABLE_PREFIX."buddyrequests (
890				 id serial,
891				 uid int NOT NULL,
892				 touid int NOT NULL,
893				 date int NOT NULL,
894				 PRIMARY KEY (id)
895			);");
896			break;
897		case "sqlite":
898			$db->write_query("CREATE TABLE ".TABLE_PREFIX."buddyrequests (
899				 id INTEGER PRIMARY KEY,
900				 uid bigint unsigned NOT NULL,
901				 touid bigint unsigned NOT NULL,
902				 date int unsigned NOT NULL
903			);");
904			break;
905		default:
906			$db->write_query("CREATE TABLE ".TABLE_PREFIX."buddyrequests (
907				 id int(10) UNSIGNED NOT NULL auto_increment,
908				 uid bigint(30) UNSIGNED NOT NULL,
909				 touid bigint(30) UNSIGNED NOT NULL,
910				 date int(11) UNSIGNED NOT NULL,
911				 KEY (uid),
912				 KEY (touid),
913				 PRIMARY KEY (id)
914			) ENGINE=MyISAM{$collation};");
915			break;
916	}
917
918	if($db->field_exists('msn', 'users'))
919	{
920		$db->drop_column("users", "msn");
921	}
922
923	if($db->field_exists('postbit', 'profilefields'))
924	{
925		$db->drop_column("profilefields", "postbit");
926	}
927
928	if($db->field_exists('skype', 'users'))
929	{
930		$db->drop_column("users", "skype");
931	}
932
933	if($db->field_exists('google', 'users'))
934	{
935		$db->drop_column("users", "google");
936	}
937
938	if($db->field_exists('cplanguage', 'adminoptions'))
939	{
940		$db->drop_column("adminoptions", "cplanguage");
941	}
942
943	if($db->field_exists('showimages', 'users'))
944	{
945		$db->drop_column("users", "showimages");
946	}
947
948	if($db->field_exists('showvideos', 'users'))
949	{
950		$db->drop_column("users", "showvideos");
951	}
952
953	if($db->field_exists('caninvitemembers', 'groupleaders'))
954	{
955		$db->drop_column("groupleaders", "caninvitemembers");
956	}
957
958	if($db->field_exists('invite', 'joinrequests'))
959	{
960		$db->drop_column("joinrequests", "invite");
961	}
962
963	if($db->field_exists('registration', 'profilefields'))
964	{
965		$db->drop_column("profilefields", "registration");
966	}
967
968	if($db->field_exists('validated', 'awaitingactivation'))
969	{
970		$db->drop_column("awaitingactivation", "validated");
971	}
972
973	if($db->field_exists('sourceeditor', 'users'))
974	{
975		$db->drop_column("users", "sourceeditor");
976	}
977
978	if($db->field_exists('buddyrequestspm', 'users'))
979	{
980		$db->drop_column("users", "buddyrequestspm");
981	}
982
983	if($db->field_exists('buddyrequestsauto', 'users'))
984	{
985		$db->drop_column("users", "buddyrequestsauto");
986	}
987
988	if($db->field_exists('ipaddress', 'privatemessages'))
989	{
990		$db->drop_column("privatemessages", "ipaddress");
991	}
992
993	if($db->field_exists('maxoptions', 'polls'))
994	{
995		$db->drop_column("polls", "maxoptions");
996	}
997
998	switch($db->type)
999	{
1000		case "pgsql":
1001			$db->add_column("profilefields", "postbit", "smallint NOT NULL default '0' AFTER profile");
1002			$db->add_column("users", "skype", "varchar(75) NOT NULL default '' AFTER yahoo");
1003			$db->add_column("users", "google", "varchar(75) NOT NULL default '' AFTER skype");
1004			$db->add_column("adminoptions", "cplanguage", "varchar(50) NOT NULL default '' AFTER cpstyle");
1005			$db->add_column("users", "showimages", "smallint NOT NULL default '1' AFTER threadmode");
1006			$db->add_column("users", "showvideos", "smallint NOT NULL default '1' AFTER showimages");
1007			$db->add_column("users", "buddyrequestspm", "smallint NOT NULL default '1' AFTER pmnotify");
1008			$db->add_column("users", "buddyrequestsauto", "smallint NOT NULL default '0' AFTER buddyrequestspm");
1009			$db->add_column("groupleaders", "caninvitemembers", "smallint NOT NULL default '0'");
1010			$db->add_column("joinrequests", "invite", "smallint NOT NULL default '0'");
1011			$db->add_column("profilefields", "registration", "smallint NOT NULL default '0' AFTER required");
1012			$db->add_column("awaitingactivation", "validated", "smallint NOT NULL default '0' AFTER type");
1013			$db->add_column("users", "sourceeditor", "smallint NOT NULL default '0'");
1014			break;
1015		default:
1016			$db->add_column("profilefields", "postbit", "tinyint(1) NOT NULL default '0' AFTER profile");
1017			$db->add_column("users", "skype", "varchar(75) NOT NULL default '' AFTER yahoo");
1018			$db->add_column("users", "google", "varchar(75) NOT NULL default '' AFTER skype");
1019			$db->add_column("adminoptions", "cplanguage", "varchar(50) NOT NULL default '' AFTER cpstyle");
1020			$db->add_column("users", "showimages", "tinyint(1) NOT NULL default '1' AFTER threadmode");
1021			$db->add_column("users", "showvideos", "tinyint(1) NOT NULL default '1' AFTER showimages");
1022			$db->add_column("users", "buddyrequestspm", "tinyint(1) NOT NULL default '1' AFTER pmnotify");
1023			$db->add_column("users", "buddyrequestsauto", "tinyint(1) NOT NULL default '0' AFTER buddyrequestspm");
1024			$db->add_column("groupleaders", "caninvitemembers", "tinyint(1) NOT NULL default '0'");
1025			$db->add_column("joinrequests", "invite", "tinyint(1) NOT NULL default '0'");
1026			$db->add_column("profilefields", "registration", "tinyint(1) NOT NULL default '0' AFTER required");
1027			$db->add_column("awaitingactivation", "validated", "tinyint(1) NOT NULL default '0' AFTER type");
1028			$db->add_column("users", "sourceeditor", "tinyint(1) NOT NULL default '0'");
1029			break;
1030	}
1031
1032	switch($db->type)
1033	{
1034		case "pgsql":
1035			$db->add_column("privatemessages", "ipaddress", "bytea NOT NULL default ''");
1036			$db->add_column("polls", "maxoptions", "smallint NOT NULL default '0'");
1037			break;
1038		case "sqlite":
1039			$db->add_column("privatemessages", "ipaddress", "blob(16) NOT NULL default ''");
1040			$db->add_column("polls", "maxoptions", "smallint NOT NULL default '0'");
1041			break;
1042		default:
1043			$db->add_column("privatemessages", "ipaddress", "varbinary(16) NOT NULL default ''");
1044			$db->add_column("polls", "maxoptions", "smallint unsigned NOT NULL default '0'");
1045			break;
1046	}
1047
1048	$groups = range(1, 39);
1049
1050	$sql = implode(',', $groups);
1051	$db->update_query("templategroups", array('isdefault' => 1), "gid IN ({$sql})");
1052
1053	if($db->table_exists('reportedposts'))
1054	{
1055		$db->update_query("reportedposts", array('type' => 'post'));
1056	}
1057
1058	$db->insert_query("questions", array('question' => 'What does 2 + 2 equal?', 'answer' => '4\nFour', 'active' => '1'));
1059
1060	$query = $db->simple_select("attachtypes", "COUNT(*) as numexists", "extension='psd'");
1061	if($db->fetch_field($query, "numexists") == 0)
1062	{
1063		$db->insert_query("attachtypes", array('name' => "Adobe Photoshop File", 'mimetype' => 'application/x-photoshop', 'extension' => "psd", 'maxsize' => '1024', 'icon' => 'images/attachtypes/psd.png'));
1064	}
1065	// SQLite... As we modify tables below we need to close all cursors before...
1066	if($db->type == "sqlite")
1067	{
1068		$query->closeCursor();
1069	}
1070
1071	$query = $db->simple_select("templategroups", "COUNT(*) as numexists", "prefix='video'");
1072	if($db->fetch_field($query, "numexists") == 0)
1073	{
1074		$db->insert_query("templategroups", array('prefix' => 'video', 'title' => '<lang:group_video>', 'isdefault' => '1'));
1075	}
1076	// SQLite... As we modify tables below we need to close all cursors before...
1077	if($db->type == "sqlite")
1078	{
1079		$query->closeCursor();
1080	}
1081
1082	$query = $db->simple_select("templategroups", "COUNT(*) as numexists", "prefix='php'");
1083	if($db->fetch_field($query, "numexists") != 0)
1084	{
1085		$db->update_query("templategroups", array('prefix' => 'announcement', 'title' => '<lang:group_announcement>'), "prefix='php'");
1086	}
1087	// SQLite... As we modify tables below we need to close all cursors before...
1088	if($db->type == "sqlite")
1089	{
1090		$query->closeCursor();
1091	}
1092
1093	$query = $db->simple_select("templategroups", "COUNT(*) as numexists", "prefix='redirect'");
1094	if($db->fetch_field($query, "numexists") != 0)
1095	{
1096		$db->update_query("templategroups", array('prefix' => 'posticons', 'title' => '<lang:group_posticons>'), "prefix='redirect'");
1097	}
1098	// SQLite... As we modify tables below we need to close all cursors before...
1099	if($db->type == "sqlite")
1100	{
1101		$query->closeCursor();
1102	}
1103
1104	// Sync usergroups with canbereported; no moderators or banned groups
1105	echo "<p>Updating usergroup permissions...</p>";
1106	$groups = array();
1107	$usergroups = $cache->read('usergroups');
1108
1109	foreach($usergroups as $group)
1110	{
1111		if($group['canmodcp'] || $group['isbannedgroup'])
1112		{
1113			continue;
1114		}
1115
1116		$groups[] = "'{$group['gid']}'";
1117	}
1118
1119	if(!empty($groups))
1120	{
1121		$usergroups = implode(',', $groups);
1122		$db->update_query('usergroups', array('canbereported' => 1), "gid IN ({$usergroups})");
1123	}
1124
1125	$db->update_query('usergroups', array('canviewboardclosed' => 1), 'cancp = 1');
1126
1127	if($db->table_exists('reportedposts'))
1128	{
1129		if($db->field_exists("pid", "reportedposts") && !$db->field_exists("id", "reportedposts"))
1130		{
1131			switch($db->type)
1132			{
1133				case "pgsql":
1134					$db->rename_column("reportedposts", "pid", "id", "int", true, "'0'");
1135					break;
1136				default:
1137					$db->rename_column("reportedposts", "pid", "id", "int unsigned NOT NULL default '0'");
1138			}
1139		}
1140
1141		if($db->field_exists("tid", "reportedposts") && !$db->field_exists("id2", "reportedposts"))
1142		{
1143			switch($db->type)
1144			{
1145				case "pgsql":
1146					$db->rename_column("reportedposts", "tid", "id2", "int", true, "'0'");
1147					break;
1148				default:
1149					$db->rename_column("reportedposts", "tid", "id2", "int unsigned NOT NULL default '0'");
1150			}
1151		}
1152
1153		if($db->field_exists("fid", "reportedposts") && !$db->field_exists("id3", "reportedposts"))
1154		{
1155			switch($db->type)
1156			{
1157				case "pgsql":
1158					$db->rename_column("reportedposts", "fid", "id3", "int", true, "'0'");
1159					break;
1160				default:
1161					$db->rename_column("reportedposts", "fid", "id3", "int unsigned NOT NULL default '0'");
1162			}
1163		}
1164	}
1165
1166	if($db->table_exists('reportedposts'))
1167	{
1168		if($db->table_exists("reportedcontent"))
1169		{
1170			$db->drop_table("reportedcontent");
1171		}
1172
1173		$db->rename_table("reportedposts", "reportedcontent");
1174
1175		$cache->delete('reportedposts');
1176	}
1177
1178	$db->update_query("settings", array('optionscode' => 'select\r\n0=No CAPTCHA\r\n1=MyBB Default CAPTCHA\r\n2=reCAPTCHA\r\n3=Are You a Human'), "name='captchaimage'");
1179	$db->update_query("settings", array('optionscode' => 'select\r\ninstant=Instant Activation\r\nverify=Send Email Verification\r\nrandompass=Send Random Password\r\nadmin=Administrator Activation\r\nboth=Email Verification & Administrator Activation'), "name='regtype'");
1180	$db->update_query("settings", array('optionscode' => $db->escape_string('php
1181<select name=\"upsetting[{$setting[\'name\']}]\">
1182<option value=\"-12\" ".($setting[\'value\'] == -12?"selected=\"selected\"":"").">GMT -12:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -12).")</option>
1183<option value=\"-11\" ".($setting[\'value\'] == -11?"selected=\"selected\"":"").">GMT -11:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -11).")</option>
1184<option value=\"-10\" ".($setting[\'value\'] == -10?"selected=\"selected\"":"").">GMT -10:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -10).")</option>
1185<option value=\"-9.5\" ".($setting[\'value\'] == -9.5?"selected=\"selected\"":"").">GMT -9:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -9.5).")</option>
1186<option value=\"-9\" ".($setting[\'value\'] == -9?"selected=\"selected\"":"").">GMT -9:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -9).")</option>
1187<option value=\"-8\" ".($setting[\'value\'] == -8?"selected=\"selected\"":"").">GMT -8:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -8).")</option>
1188<option value=\"-7\" ".($setting[\'value\'] == -7?"selected=\"selected\"":"").">GMT -7:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -7).")</option>
1189<option value=\"-6\" ".($setting[\'value\'] == -6?"selected=\"selected\"":"").">GMT -6:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -6).")</option>
1190<option value=\"-5\" ".($setting[\'value\'] == -5?"selected=\"selected\"":"").">GMT -5:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -5).")</option>
1191<option value=\"-4.5\" ".($setting[\'value\'] == -4.5?"selected=\"selected\"":"").">GMT -4:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -4.5).")</option>
1192<option value=\"-4\" ".($setting[\'value\'] == -4?"selected=\"selected\"":"").">GMT -4:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -4).")</option>
1193<option value=\"-3.5\" ".($setting[\'value\'] == -3.5?"selected=\"selected\"":"").">GMT -3:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -3.5).")</option>
1194<option value=\"-3\" ".($setting[\'value\'] == -3?"selected=\"selected\"":"").">GMT -3:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -3).")</option>
1195<option value=\"-2\" ".($setting[\'value\'] == -2?"selected=\"selected\"":"").">GMT -2:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -2).")</option>
1196<option value=\"-1\" ".($setting[\'value\'] == -1?"selected=\"selected\"":"").">GMT -1:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, -1).")</option>
1197<option value=\"0\" ".($setting[\'value\'] == 0?"selected=\"selected\"":"").">GMT (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 0).")</option>
1198<option value=\"+1\" ".($setting[\'value\'] == 1?"selected=\"selected\"":"").">GMT +1:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 1).")</option>
1199<option value=\"+2\" ".($setting[\'value\'] == 2?"selected=\"selected\"":"").">GMT +2:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 2).")</option>
1200<option value=\"+3\" ".($setting[\'value\'] == 3?"selected=\"selected\"":"").">GMT +3:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 3).")</option>
1201<option value=\"+3.5\" ".($setting[\'value\'] == 3.5?"selected=\"selected\"":"").">GMT +3:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 3.5).")</option>
1202<option value=\"+4\" ".($setting[\'value\'] == 4?"selected=\"selected\"":"").">GMT +4:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 4).")</option>
1203<option value=\"+4.5\" ".($setting[\'value\'] == 4.5?"selected=\"selected\"":"").">GMT +4:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 4.5).")</option>
1204<option value=\"+5\" ".($setting[\'value\'] == 5?"selected=\"selected\"":"").">GMT +5:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 5).")</option>
1205<option value=\"+5.5\" ".($setting[\'value\'] == 5.5?"selected=\"selected\"":"").">GMT +5:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 5.5).")</option>
1206<option value=\"+5.75\" ".($setting[\'value\'] == 5.75?"selected=\"selected\"":"").">GMT +5:45 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 5.75).")</option>
1207<option value=\"+6\" ".($setting[\'value\'] == 6?"selected=\"selected\"":"").">GMT +6:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 6).")</option>
1208<option value=\"+6.5\" ".($setting[\'value\'] == 6.5?"selected=\"selected\"":"").">GMT +6:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 6.5).")</option>
1209<option value=\"+7\" ".($setting[\'value\'] == 7?"selected=\"selected\"":"").">GMT +7:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 7).")</option>
1210<option value=\"+8\" ".($setting[\'value\'] == 8?"selected=\"selected\"":"").">GMT +8:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 8).")</option>
1211<option value=\"+9\" ".($setting[\'value\'] == 9?"selected=\"selected\"":"").">GMT +9:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 9).")</option>
1212<option value=\"+9.5\" ".($setting[\'value\'] == 9.5?"selected=\"selected\"":"").">GMT +9:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 9.5).")</option>
1213<option value=\"+10\" ".($setting[\'value\'] == 10?"selected=\"selected\"":"").">GMT +10:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 10).")</option>
1214<option value=\"+10.5\" ".($setting[\'value\'] == 10.5?"selected=\"selected\"":"").">GMT +10:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 10.5).")</option>
1215<option value=\"+11\" ".($setting[\'value\'] == 11?"selected=\"selected\"":"").">GMT +11:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 11).")</option>
1216<option value=\"+11.5\" ".($setting[\'value\'] == 11.5?"selected=\"selected\"":"").">GMT +11:30 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 11.5).")</option>
1217<option value=\"+12\" ".($setting[\'value\'] == 12?"selected=\"selected\"":"").">GMT +12:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 12).")</option>
1218<option value=\"+12.75\" ".($setting[\'value\'] == 12.75?"selected=\"selected\"":"").">GMT +12:45 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 12.75).")</option>
1219<option value=\"+13\" ".($setting[\'value\'] == 13?"selected=\"selected\"":"").">GMT +13:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 13).")</option>
1220<option value=\"+14\" ".($setting[\'value\'] == 14?"selected=\"selected\"":"").">GMT +14:00 Hours (".my_date($mybb->settings[\'timeformat\'], TIME_NOW, 14).")</option>
1221</select>')), "name='timezoneoffset'");
1222
1223	// Update tasks
1224	$added_tasks = sync_tasks();
1225
1226	// For the version check task, set a random date and hour (so all MyBB installs don't query mybb.com all at the same time)
1227	$update_array = array(
1228		'hour' => rand(0, 23),
1229		'weekday' => rand(0, 6)
1230	);
1231
1232	$db->update_query("tasks", $update_array, "file = 'versioncheck'");
1233
1234	echo "<p>Added {$added_tasks} new tasks.</p>";
1235
1236	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
1237	$output->print_footer("30_threadcount");
1238}
1239
1240function upgrade30_threadcount()
1241{
1242	global $db, $output;
1243
1244	$output->print_header("Counting user thread count");
1245
1246	if(!$_POST['theadspage'])
1247	{
1248		$threads = 500;
1249	}
1250	else
1251	{
1252		$threads = (int)$_POST['theadspage'];
1253	}
1254
1255	if($_POST['threadstart'])
1256	{
1257		$startat = (int)$_POST['threadstart'];
1258		$upper = $startat+$threads;
1259		$lower = $startat;
1260	}
1261	else
1262	{
1263		$startat = 0;
1264		$upper = $threads;
1265		$lower = 0;
1266	}
1267
1268	$query = $db->simple_select("users", "COUNT(uid) AS usercount");
1269	$cnt = $db->fetch_array($query);
1270
1271	if($upper > $cnt['usercount'])
1272	{
1273		$upper = $cnt['usercount'];
1274	}
1275
1276	echo "<p>Counting thread count of user #{$lower} to #{$upper} ({$cnt['usercount']} Total)</p>";
1277	flush();
1278
1279	$threadnum = false;
1280
1281	$query = $db->simple_select("users", "threadnum, uid", "", array('limit_start' => $lower, 'limit' => $threads));
1282	while($thread = $db->fetch_array($query))
1283	{
1284		$query2 = $db->simple_select("threads", "COUNT(tid) AS thread_count", "uid='{$thread['uid']}' AND visible = 1");
1285		$num_threads = $db->fetch_field($query2, "thread_count");
1286
1287		$db->update_query("users", array('threadnum' => $num_threads), "uid = '{$thread['uid']}'");
1288
1289		$threadnum = true;
1290	}
1291
1292	$remaining = $upper-$cnt['usercount'];
1293	if($remaining && $threadnum)
1294	{
1295		$nextact = "30_threadcount";
1296		$startat = $startat+$threads;
1297		$contents = "<p><input type=\"hidden\" name=\"theadspage\" value=\"$threads\" /><input type=\"hidden\" name=\"threadstart\" value=\"$startat\" />Done. Click Next to move on to the next set of thread counts.</p>";
1298	}
1299	else
1300	{
1301		$nextact = "30_dbchanges_optimize1";
1302		$contents = "<p>Done</p><p>All users have had their thread count counted. Click next to continue.</p>";
1303	}
1304	$output->print_contents($contents);
1305
1306	global $footer_extra;
1307	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
1308
1309	$output->print_footer($nextact);
1310}
1311
1312function upgrade30_dbchanges_optimize1()
1313{
1314	global $output, $mybb, $db;
1315
1316	$output->print_header("Optimizing Database");
1317
1318	echo "<p>Performing necessary optimization queries...</p>";
1319	flush();
1320
1321	switch($db->type)
1322	{
1323		case "pgsql":
1324			$db->modify_column("adminoptions", "loginattempts", "smallint", "set", "'0'");
1325			$db->modify_column("adminviews", "perpage", "smallint", "set", "'0'");
1326			$db->modify_column("calendars", "disporder", "smallint", "set", "'0'");
1327			$db->modify_column("calendars", "eventlimit", "smallint", "set", "'0'");
1328			$db->modify_column("events", "timezone", "varchar(5)", "set", "''");
1329			$db->modify_column("forums", "lastposttid", "int", "set", "'0'");
1330			$db->modify_column("mailerrors", "smtpcode", "smallint", "set", "'0'");
1331			$db->modify_column("maillogs", "touid", "int", "set", "'0'");
1332			$db->write_query("ALTER TABLE ".TABLE_PREFIX."polls ALTER COLUMN numvotes DROP DEFAULT"); // We need to drop the default first as PostgreSQL can't cast default values
1333			$db->modify_column("polls", "numvotes", "int USING (trim(numvotes)::int)", "set", "'0'");
1334			$db->modify_column("profilefields", "postnum", "smallint", "set", "'0'");
1335			$db->modify_column("reputation", "reputation", "smallint", "set", "'0'");
1336			$db->modify_column("spiders", "theme", "smallint", "set", "'0'");
1337			$db->modify_column("spiders", "usergroup", "smallint", "set", "'0'");
1338			$db->modify_column("templates", "sid", "smallint", "set", "'0'");
1339			$db->modify_column("themestylesheets", "tid", "smallint", "set", "'0'");
1340			$db->modify_column("usergroups", "canusesigxposts", "smallint", "set", "'0'");
1341			$db->modify_column("users", "timezone", "varchar(5)", "set", "''");
1342			$db->modify_column("users", "reputation", "int", "set", "'0'");
1343			$db->modify_column("warninglevels", "percentage", "smallint", "set", "'0'");
1344			$db->modify_column("warningtypes", "points", "smallint", "set", "'0'");
1345			$db->modify_column("warnings", "points", "smallint", "set", "'0'");
1346			break;
1347		case "sqlite":
1348			$db->modify_column("adminoptions", "loginattempts", "smallint NOT NULL default '0'");
1349			$db->modify_column("adminviews", "perpage", "smallint NOT NULL default '0'");
1350			$db->modify_column("calendars", "disporder", "smallint NOT NULL default '0'");
1351			$db->modify_column("calendars", "eventlimit", "smallint NOT NULL default '0'");
1352			$db->modify_column("events", "timezone", "varchar(5) NOT NULL default ''");
1353			$db->modify_column("forums", "lastposttid", "int NOT NULL default '0'");
1354			$db->modify_column("mailerrors", "smtpcode", "smallint NOT NULL default '0'");
1355			$db->modify_column("maillogs", "touid", "int NOT NULL default '0'");
1356			$db->modify_column("polls", "numvotes", "int NOT NULL default '0'");
1357			$db->modify_column("profilefields", "postnum", "smallint NOT NULL default '0'");
1358			$db->modify_column("reputation", "reputation", "smallint NOT NULL default '0'");
1359			$db->modify_column("spiders", "theme", "smallint NOT NULL default '0'");
1360			$db->modify_column("spiders", "usergroup", "smallint NOT NULL default '0'");
1361			$db->modify_column("templates", "sid", "smallint NOT NULL default '0'");
1362			$db->modify_column("themestylesheets", "tid", "smallint NOT NULL default '0'");
1363			$db->modify_column("usergroups", "canusesigxposts", "smallint NOT NULL default '0'");
1364			$db->modify_column("users", "timezone", "varchar(5) NOT NULL default ''");
1365			$db->modify_column("users", "reputation", "int NOT NULL default '0'");
1366			$db->modify_column("warninglevels", "percentage", "smallint NOT NULL default '0'");
1367			$db->modify_column("warningtypes", "points", "smallint NOT NULL default '0'");
1368			$db->modify_column("warnings", "points", "smallint NOT NULL default '0'");
1369			break;
1370		default:
1371			$db->modify_column("adminoptions", "loginattempts", "smallint unsigned NOT NULL default '0'");
1372			$db->modify_column("adminviews", "perpage", "smallint(4) NOT NULL default '0'");
1373			$db->modify_column("calendars", "disporder", "smallint unsigned NOT NULL default '0'");
1374			$db->modify_column("calendars", "eventlimit", "smallint(3) NOT NULL default '0'");
1375			$db->modify_column("events", "timezone", "varchar(5) NOT NULL default ''");
1376			$db->modify_column("forums", "lastposttid", "int unsigned NOT NULL default '0'");
1377			$db->modify_column("mailerrors", "smtpcode", "smallint(5) unsigned NOT NULL default '0'");
1378			$db->modify_column("maillogs", "touid", "int unsigned NOT NULL default '0'");
1379			$db->modify_column("polls", "numvotes", "int unsigned NOT NULL default '0'");
1380			$db->modify_column("profilefields", "postnum", "smallint unsigned NOT NULL default '0'");
1381			$db->modify_column("reputation", "reputation", "smallint NOT NULL default '0'");
1382			$db->modify_column("spiders", "theme", "smallint unsigned NOT NULL default '0'");
1383			$db->modify_column("spiders", "usergroup", "smallint unsigned NOT NULL default '0'");
1384			$db->modify_column("templates", "sid", "smallint NOT NULL default '0'");
1385			$db->modify_column("themestylesheets", "tid", "smallint unsigned NOT NULL default '0'");
1386			$db->modify_column("usergroups", "canusesigxposts", "smallint unsigned NOT NULL default '0'");
1387			$db->modify_column("users", "timezone", "varchar(5) NOT NULL default ''");
1388			$db->modify_column("users", "reputation", "int NOT NULL default '0'");
1389			$db->modify_column("warninglevels", "percentage", "smallint(3) NOT NULL default '0'");
1390			$db->modify_column("warningtypes", "points", "smallint unsigned NOT NULL default '0'");
1391			$db->modify_column("warnings", "points", "smallint unsigned NOT NULL default '0'");
1392			break;
1393	}
1394
1395	if($db->type != "pgsql")
1396	{
1397		// PgSQL doesn't support longtext
1398		if($db->type == "sqlite")
1399		{
1400			// And SQLite doesn't like text columns without a default value...
1401			$db->modify_column("themestylesheets", "stylesheet", "longtext NOT NULL default ''");
1402		}
1403		else
1404		{
1405			// ...while MySQL hates text columns with a default value
1406			$db->modify_column("themestylesheets", "stylesheet", "longtext NOT NULL");
1407		}
1408	}
1409
1410	global $footer_extra;
1411	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
1412
1413	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
1414	$output->print_footer("30_dbchanges_optimize2");
1415}
1416
1417function upgrade30_dbchanges_optimize2()
1418{
1419	global $output, $mybb, $db;
1420
1421	$output->print_header("Optimizing Database");
1422
1423	echo "<p>Performing necessary optimization queries...</p>";
1424	echo "<p>Adding indexes to tables...</p>";
1425	flush();
1426
1427	if($db->index_exists('sessions', 'location1'))
1428	{
1429		$db->drop_index('sessions', 'location1');
1430	}
1431
1432	if($db->index_exists('sessions', 'location2'))
1433	{
1434		$db->drop_index('sessions', 'location2');
1435	}
1436
1437	if($db->type == "mysql" || $db->type == "mysqli")
1438	{
1439		$update_data = array(
1440			'adminlog' => 'uid',
1441			'banfilters' => 'type',
1442			'events' => 'cid',
1443			'forumsubscriptions' => 'uid',
1444			'moderatorlog' => array('uid', 'fid'),
1445			'polls' => 'tid',
1446			'reportedcontent' => 'reportstatus',
1447			'settings' => 'gid',
1448			'themestylesheets' => 'tid',
1449			'warnings' => 'uid',
1450			'forumpermissions' => array('fid' => array('fid', 'gid')),
1451			'sessions' => array('location' => array('location1', 'location2')),
1452			'templates' => array('sid' => array('sid', 'title'))
1453		);
1454
1455		foreach($update_data as $table => $index)
1456		{
1457			if(!is_array($index))
1458			{
1459				$index = array($index);
1460			}
1461
1462			foreach($index as $_index => $keys)
1463			{
1464				if(!is_array($keys))
1465				{
1466					if(!$db->index_exists($table, $keys))
1467					{
1468						$db->write_query("ALTER TABLE ".TABLE_PREFIX."{$table} ADD INDEX (`{$keys}`)");
1469					}
1470				}
1471				else
1472				{
1473					if(!$db->index_exists($table, $_index))
1474					{
1475						$db->write_query("ALTER TABLE ".TABLE_PREFIX."{$table} ADD INDEX `{$_index}`(`".implode('`, `', $keys)."`)");
1476					}
1477				}
1478			}
1479		}
1480	}
1481
1482	echo "<p>Dropping old indexes from tables...</p>";
1483
1484	if($db->index_exists('attachments', 'posthash'))
1485	{
1486		$db->drop_index('attachments', 'posthash');
1487	}
1488
1489	if($db->index_exists('reportedcontent', 'dateline'))
1490	{
1491		$db->drop_index('reportedcontent', 'dateline');
1492	}
1493
1494	if($db->index_exists('reputation', 'pid'))
1495	{
1496		$db->drop_index('reputation', 'pid');
1497	}
1498
1499	if($db->index_exists('reputation', 'dateline'))
1500	{
1501		$db->drop_index('reputation', 'dateline');
1502	}
1503
1504	if($db->index_exists('users', 'birthday'))
1505	{
1506		$db->drop_index('users', 'birthday');
1507	}
1508
1509	global $footer_extra;
1510	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
1511
1512	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
1513	$output->print_footer("30_dbchanges_optimize3");
1514}
1515
1516function upgrade30_dbchanges_optimize3()
1517{
1518	global $cache, $output, $mybb, $db;
1519
1520	$output->print_header("Optimizing Database");
1521
1522	echo "<p>Performing necessary optimization queries...</p>";
1523	flush();
1524
1525	$to_tinyint = array(
1526		"adminoptions" => array("codepress"),
1527		"adminviews" => array("visibility"),
1528		"announcements" => array("allowhtml", "allowmycode", "allowsmilies"),
1529		"attachments" => array("visible"),
1530		"banfilters" => array("type"),
1531		"calendars" => array("startofweek", "showbirthdays", "moderation", "allowhtml", "allowmycode", "allowimgcode", "allowvideocode", "allowsmilies"),
1532		"calendarpermissions" => array("canviewcalendar", "canaddevents", "canbypasseventmod", "canmoderateevents"),
1533		"events" => array("visible", "private", "ignoretimezone", "usingtime"),
1534		"forumpermissions" => array("canview", "canviewthreads", "canonlyviewownthreads", "candlattachments", "canpostthreads", "canpostreplys", "canpostattachments", "canratethreads", "caneditposts", "candeleteposts", "candeletethreads", "caneditattachments", "canpostpolls", "canvotepolls", "cansearch"),
1535		"forums" => array("active", "open", "allowhtml", "allowmycode", "allowsmilies", "allowimgcode", "allowvideocode", "allowpicons", "allowtratings", "usepostcounts", "showinjump", "overridestyle", "rulestype"),
1536		"groupleaders" => array("canmanagemembers", "canmanagerequests"),
1537		"helpdocs" => array("usetranslation", "enabled"),
1538		"helpsections" => array("usetranslation", "enabled"),
1539		"moderators" => array("isgroup", "caneditposts", "candeleteposts", "canviewips", "canopenclosethreads", "canmanagethreads", "canmovetononmodforum", "canusecustomtools"),
1540		"mycode" => array("active"),
1541		"polls" => array("closed", "multiple", "public"),
1542		"posts" => array("includesig", "smilieoff", "visible"),
1543		"privatemessages" => array("status", "includesig", "smilieoff", "receipt"),
1544		"profilefields" => array("required"),
1545		"reportedcontent" => array("reportstatus"),
1546		"sessions" => array("anonymous", "nopermission"),
1547		"settinggroups" => array("isdefault"),
1548		"settings" => array("isdefault"),
1549		"smilies" => array("showclickable"),
1550		"tasks" => array("enabled", "logging"),
1551		"themes" => array("def"),
1552		"threads" => array("sticky", "visible"),
1553		"threadsubscriptions" => array("notification"),
1554		"usergroups" => array("isbannedgroup", "canview", "canviewthreads", "canviewprofiles", "candlattachments", "canviewboardclosed", "canpostthreads", "canpostreplys", "canpostattachments", "canratethreads", "caneditposts", "candeleteposts", "candeletethreads", "caneditattachments", "canpostpolls", "canvotepolls", "canundovotes", "canusepms", "cansendpms", "cantrackpms", "candenypmreceipts", "cansendemail", "cansendemailoverride", "canviewmemberlist", "canviewcalendar", "canaddevents", "canbypasseventmod", "canmoderateevents", "canviewonline", "canviewwolinvis", "canviewonlineips", "cancp", "issupermod", "cansearch", "canusercp", "canuploadavatars", "canratemembers", "canchangename", "canbereported", "showforumteam", "usereputationsystem", "cangivereputations", "candisplaygroup", "cancustomtitle", "canwarnusers", "canreceivewarnings", "canmodcp", "showinbirthdaylist", "canoverridepm", "canusesig", "signofollow"),
1555		"users" => array("allownotices", "hideemail", "subscriptionmethod", "invisible", "receivepms", "receivefrombuddy", "pmnotice", "pmnotify", "showsigs", "showavatars", "showquickreply", "showredirect", "showcodebuttons", "coppauser", "classicpostbit"),
1556		"warnings" => array("expired")
1557	);
1558
1559	foreach($to_tinyint as $table => $columns)
1560	{
1561		echo "<p>{$table}: Converting column type to tinyint</p>";
1562		$change_column = array();
1563		foreach($columns as $column)
1564		{
1565			if($db->type == "pgsql")
1566			{
1567				$db->modify_column($table, $column, "smallint", "set", "'0'");
1568			}
1569			else if($db->type == "sqlite")
1570			{
1571				$change_column[] = "CHANGE {$column} {$column} tinyint(1) NOT NULL default '0'";
1572			}
1573			else
1574			{
1575				$change_column[] = "MODIFY {$column} tinyint(1) NOT NULL default '0'";
1576			}
1577		}
1578		if($db->type != "pgsql")
1579		{
1580			$db->write_query("ALTER TABLE ".TABLE_PREFIX."{$table} ".implode(", ", $change_column));
1581		}
1582	}
1583
1584	global $footer_extra;
1585	$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
1586
1587	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
1588	$output->print_footer("30_dbchanges_optimize4");
1589}
1590
1591function upgrade30_dbchanges_optimize4()
1592{
1593	global $cache, $output, $mybb, $db;
1594
1595	$output->print_header("Optimizing Database");
1596
1597	echo "<p>Performing necessary optimization queries...</p>";
1598	flush();
1599
1600	$to_int = array(
1601		"adminlog" => array("dateline"),
1602		"adminsessions" => array("dateline", "lastactive"),
1603		"announcements" => array("startdate", "enddate"),
1604		"attachments" => array("dateuploaded"),
1605		"awaitingactivation" => array("dateline"),
1606		"banfilters" => array("lastuse", "dateline"),
1607		"banned" => array("dateline", "lifted"),
1608		"captcha" => array("dateline"),
1609		"delayedmoderation" => array("delaydateline", "dateline"),
1610		"forumsread" => array("dateline"),
1611		"joinrequests" => array("dateline"),
1612		"massemails" => array("dateline", "senddate"),
1613		"mailerrors" => array("dateline"),
1614		"maillogs" => array("dateline"),
1615		"moderatorlog" => array("dateline"),
1616		"polls" => array("dateline", "timeout"),
1617		"pollvotes" => array("dateline"),
1618		"posts" => array("dateline", "edittime"),
1619		"privatemessages" => array("dateline", "deletetime", "statustime", "readtime"),
1620		"promotionlogs" => array("dateline"),
1621		"reportedcontent" => array("dateline", "lastreport"),
1622		"reputation" => array("dateline"),
1623		"searchlog" => array("dateline"),
1624		"sessions" => array("time"),
1625		"spiders" => array("lastvisit"),
1626		"stats" => array("dateline"),
1627		"tasks" => array("nextrun", "lastrun", "locked"),
1628		"tasklog" => array("dateline"),
1629		"templates" => array("dateline"),
1630		"themestylesheets" => array("lastmodified"),
1631		"threads" => array("dateline", "lastpost"),
1632		"threadsread" => array("dateline"),
1633		"threadsubscriptions" => array("dateline"),
1634		"usergroups" => array("reputationpower", "maxreputationsday", "maxreputationsperuser", "maxreputationsperthread", "attachquota"),
1635		"users" => array("regdate", "lastactive", "lastvisit", "lastpost", "timeonline", "moderationtime", "suspensiontime", "suspendsigtime"),
1636		"warningtypes" => array("expirationtime"),
1637		"warnings" => array("dateline", "expires", "daterevoked")
1638	);
1639
1640	foreach($to_int as $table => $columns)
1641	{
1642		echo "<p>{$table}: Converting column type to int</p>";
1643		$change_column = array();
1644		foreach($columns as $column)
1645		{
1646			if($db->type == "pgsql")
1647			{
1648				$db->modify_column($table, $column, "int", "set", "'0'");
1649			}
1650			else if($db->type == "sqlite")
1651			{
1652				$change_column[] = "CHANGE {$column} {$column} int unsigned NOT NULL default '0'";
1653			}
1654			else
1655			{
1656				$change_column[] = "MODIFY {$column} int unsigned NOT NULL default '0'";
1657			}
1658		}
1659		if($db->type != "pgsql")
1660		{
1661			$db->write_query("ALTER TABLE ".TABLE_PREFIX."{$table} ".implode(", ", $change_column));
1662		}
1663	}
1664
1665	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
1666	$output->print_footer("30_dbchanges_smilies");
1667}
1668
1669function upgrade30_dbchanges_smilies()
1670{
1671	global $cache, $output, $db;
1672
1673	$output->print_header("Updating Smilies");
1674
1675	echo "<p>Performing necessary upgrade queries...</p>";
1676	flush();
1677
1678	if($db->type == 'pgsql')
1679	{
1680		$db->modify_column("smilies", "find", "text", "set");
1681	}
1682	else
1683	{
1684		$db->modify_column("smilies", "find", "text NOT NULL");
1685	}
1686
1687	$query = $db->simple_select('smilies', 'sid, image, find', '', array('order_by' => 'image, sid'));
1688	$last_image = null;
1689	$last_sid = 0;
1690	$skip = array();
1691	while($smilie = $db->fetch_array($query))
1692	{
1693		if(in_array($smilie['sid'], $skip))
1694		{
1695			continue;
1696		}
1697
1698		if($smilie['image'] == $last_image && $smilie['image'] != null)
1699		{
1700			$dupe_query = $db->simple_select('smilies', 'sid, find', 'image = "'.$db->escape_string($smilie['image']).'"');
1701			$dupes = '';
1702			$find = array();
1703			$skip = array();
1704			while($dupe = $db->fetch_array($dupe_query))
1705			{
1706				if($dupe['sid'] != $last_sid)
1707				{
1708					$dupes .= (int)$dupe['sid'].',';
1709					$find[] = trim($dupe['find']);
1710					$skip[] = (int)$dupe['sid'];
1711				}
1712				else
1713				{
1714					$find[] = $dupe['find'];
1715				}
1716			}
1717			$dupes = rtrim($dupes, ',');
1718			$db->delete_query('smilies', 'sid IN('.$dupes.')');
1719			$db->update_query('smilies', array('find' => implode("\n", $find)), 'sid = "'.(int)$last_sid.'"');
1720			$db->free_result($dupe_query);
1721		}
1722		else
1723		{
1724			$last_sid = $smilie['sid'];
1725			$last_image = $smilie['image'];
1726		}
1727	}
1728
1729	$cache->update_smilies();
1730
1731	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
1732	$output->print_footer("30_dbchanges_ip");
1733}
1734
1735function upgrade30_dbchanges_ip()
1736{
1737	global $mybb, $db, $output;
1738
1739	$output->print_header("IP Conversion");
1740
1741	$ipstart = $iptable = '';
1742
1743	switch($mybb->input['iptask'])
1744	{
1745		case 8:
1746			echo "<p>Adding database indices (3/3)...</p>";
1747			flush();
1748
1749			if(!$db->index_exists('users', 'lastip'))
1750			{
1751				// This may take a while
1752				if($db->type == "mysql" || $db->type == "mysqli")
1753				{
1754					$db->write_query("ALTER TABLE ".TABLE_PREFIX."users ADD INDEX lastip (lastip)");
1755				}
1756				elseif($db->type == "pgsql")
1757				{
1758					$db->write_query("ALTER TABLE ".TABLE_PREFIX."users ADD INDEX (`lastip`)");
1759				}
1760			}
1761			$next_task = 9;
1762			break;
1763		case 7:
1764			echo "<p>Adding database indices (2/3)...</p>";
1765			flush();
1766
1767			if(!$db->index_exists('users', 'regip'))
1768			{
1769				// This may take a while
1770				if($db->type == "mysql" || $db->type == "mysqli")
1771				{
1772					$db->write_query("ALTER TABLE ".TABLE_PREFIX."users ADD INDEX regip (regip)");
1773				}
1774				elseif($db->type == "pgsql")
1775				{
1776					$db->write_query("ALTER TABLE ".TABLE_PREFIX."users ADD INDEX (`regip`)");
1777				}
1778			}
1779			$next_task = 8;
1780			break;
1781		case 6:
1782			echo "<p>Adding database indices (1/3)...</p>";
1783			flush();
1784
1785			if(!$db->index_exists('posts', 'ipaddress'))
1786			{
1787				// This may take a while
1788				if($db->type == "mysql" || $db->type == "mysqli")
1789				{
1790					$db->write_query("ALTER TABLE ".TABLE_PREFIX."posts ADD INDEX ipaddress (ipaddress)");
1791				}
1792				elseif($db->type == "pgsql")
1793				{
1794					$db->write_query("ALTER TABLE ".TABLE_PREFIX."posts ADD INDEX (`ipaddress`)");
1795				}
1796			}
1797			$next_task = 7;
1798			break;
1799		case 5:
1800			if(!$_POST['ipspage'])
1801			{
1802				$ipp = 5000;
1803			}
1804			else
1805			{
1806				$ipp = (int)$_POST['ipspage'];
1807			}
1808
1809			if($_POST['ipstart'])
1810			{
1811				$startat = (int)$_POST['ipstart'];
1812				$upper = $startat+$ipp-1;
1813				$lower = $startat;
1814			}
1815			else
1816			{
1817				$startat = 0;
1818				$upper = $ipp;
1819				$lower = 0;
1820			}
1821
1822			$next_task = 5;
1823			switch($mybb->input['iptable'])
1824			{
1825				case 7:
1826					echo "<p>Converting user IPs...</p>";
1827					flush();
1828					$query = $db->simple_select("users", "COUNT(uid) AS ipcount");
1829					if($db->type == "mysql" || $db->type == "mysqli")
1830					{
1831						$next_task = 6;
1832					}
1833					else
1834					{
1835						$next_task = 9;
1836					}
1837					break;
1838				case 6:
1839					echo "<p>Converting thread rating IPs...</p>";
1840					flush();
1841					$query = $db->simple_select("threadratings", "COUNT(rid) AS ipcount");
1842					break;
1843				case 5:
1844					echo "<p>Converting session IPs...</p>";
1845					flush();
1846					$query = $db->simple_select("sessions", "COUNT(sid) AS ipcount");
1847					break;
1848				case 4:
1849					echo "<p>Converting post IPs...</p>";
1850					flush();
1851					$query = $db->simple_select("posts", "COUNT(pid) AS ipcount");
1852					break;
1853				case 3:
1854					echo "<p>Converting moderator log IPs...</p>";
1855					flush();
1856					$query = $db->simple_select("moderatorlog", "COUNT(DISTINCT ipaddress) AS ipcount");
1857					break;
1858				case 2:
1859					echo "<p>Converting mail log IPs...</p>";
1860					flush();
1861					$query = $db->simple_select("maillogs", "COUNT(mid) AS ipcount");
1862					break;
1863				default:
1864					echo "<p>Converting admin log IPs...</p>";
1865					flush();
1866					$query = $db->simple_select("adminlog", "COUNT(DISTINCT ipaddress) AS ipcount");
1867					break;
1868			}
1869			$cnt = $db->fetch_array($query);
1870
1871			if($upper > $cnt['ipcount'])
1872			{
1873				$upper = $cnt['ipcount'];
1874			}
1875
1876			echo "<p>Converting ip {$lower} to {$upper} ({$cnt['ipcount']} Total)</p>";
1877			flush();
1878
1879			$ipaddress = false;
1880
1881			switch($mybb->input['iptable'])
1882			{
1883				case 7:
1884					$query = $db->simple_select("users", "uid, regip, lastip", "", array('limit_start' => $lower, 'limit' => $ipp));
1885					break;
1886				case 6:
1887					$query = $db->simple_select("threadratings", "rid, ipaddress", "", array('limit_start' => $lower, 'limit' => $ipp));
1888					break;
1889				case 5:
1890					$query = $db->simple_select("sessions", "sid, ip", "", array('limit_start' => $lower, 'limit' => $ipp));
1891					break;
1892				case 4:
1893					$query = $db->simple_select("posts", "pid, ipaddress", "", array('limit_start' => $lower, 'limit' => $ipp));
1894					break;
1895				case 3:
1896					$query = $db->simple_select("moderatorlog", "DISTINCT(ipaddress)", "", array('limit_start' => $lower, 'limit' => $ipp));
1897					break;
1898				case 2:
1899					$query = $db->simple_select("maillogs", "mid, ipaddress", "", array('limit_start' => $lower, 'limit' => $ipp));
1900					break;
1901				default:
1902					$query = $db->simple_select("adminlog", "DISTINCT(ipaddress)", "", array('limit_start' => $lower, 'limit' => $ipp));
1903					$mybb->input['iptable'] = 1;
1904					break;
1905			}
1906			while($data = $db->fetch_array($query))
1907			{
1908				// Skip invalid IPs
1909				switch($mybb->input['iptable'])
1910				{
1911					case 7:
1912						$ip1 = my_inet_pton($db->unescape_binary($data['regip']));
1913						$ip2 = my_inet_pton($db->unescape_binary($data['lastip']));
1914						if($ip1 === false && $ip2 === false)
1915						{
1916							continue 2;
1917						}
1918						break;
1919					case 5:
1920						$ip = my_inet_pton($db->unescape_binary($data['ip']));
1921						if($ip === false)
1922						{
1923							continue 2;
1924						}
1925						break;
1926					case 6:
1927					case 4:
1928					case 3:
1929					case 2:
1930					default:
1931						$ip = my_inet_pton($db->unescape_binary($data['ipaddress']));
1932						if($ip === false)
1933						{
1934							continue 2;
1935						}
1936						break;
1937				}
1938
1939				switch($mybb->input['iptable'])
1940				{
1941					case 7:
1942						$db->update_query("users", array('regip' => $db->escape_binary($ip1), 'lastip' => $db->escape_binary($ip2)), "uid = '".(int)$data['uid']."'");
1943						break;
1944					case 6:
1945						$db->update_query("threadratings", array('ipaddress' => $db->escape_binary($ip)), "rid = '".(int)$data['rid']."'");
1946						break;
1947					case 5:
1948						$db->update_query("sessions", array('ip' => $db->escape_binary($ip)), "sid = '".(int)$data['sid']."'");
1949						break;
1950					case 4:
1951						$db->update_query("posts", array('ipaddress' => $db->escape_binary($ip)), "pid = '".(int)$data['pid']."'");
1952						break;
1953					case 3:
1954						$db->update_query("moderatorlog", array('ipaddress' => $db->escape_binary($ip)), "ipaddress = '".$db->escape_string($data['ipaddress'])."'");
1955						break;
1956					case 2:
1957						$db->update_query("maillogs", array('ipaddress' => $db->escape_binary($ip)), "mid = '".(int)$data['mid']."'");
1958						break;
1959					default:
1960						$db->update_query("adminlog", array('ipaddress' => $db->escape_binary($ip)), "ipaddress = '".$db->escape_string($data['ipaddress'])."'");
1961						break;
1962				}
1963				$ipaddress = true;
1964			}
1965
1966			$remaining = $upper-$cnt['ipcount'];
1967			if($remaining && $ipaddress)
1968			{
1969				$startat = $startat+$ipp;
1970				$ipstart = "<input type=\"hidden\" name=\"ipstart\" value=\"$startat\" />";
1971				$iptable = $mybb->input['iptable'];
1972			}
1973			else
1974			{
1975				$iptable = $mybb->input['iptable']+1;
1976			}
1977			if($iptable <= 10)
1978			{
1979				$iptable = "<input type=\"hidden\" name=\"iptable\" value=\"$iptable\" />";
1980			}
1981			break;
1982		case 4:
1983			$next_task = 4;
1984			switch($mybb->input['iptable'])
1985			{
1986				case 10:
1987					echo "<p>Updating user table (4/4)...</p>";
1988					flush();
1989
1990					$table = 'users';
1991					$column = 'lastip';
1992					$next_task = 5;
1993					break;
1994				case 9:
1995					echo "<p>Updating user table (3/4)...</p>";
1996					flush();
1997
1998					$table = 'users';
1999					$column = 'regip';
2000					break;
2001				case 8:
2002					echo "<p>Updating threadreating table...</p>";
2003					flush();
2004
2005					$table = 'threadratings';
2006					$column = 'ipaddress';
2007					break;
2008				case 7:
2009					echo "<p>Updating session table...</p>";
2010					flush();
2011
2012					$table = 'sessions';
2013					$column = 'ip';
2014					break;
2015				case 6:
2016					echo "<p>Updating searchlog table...</p>";
2017					flush();
2018
2019					$table = 'searchlog';
2020					$column = 'ipaddress';
2021					// Skip conversion
2022					$db->delete_query('searchlog');
2023					break;
2024				case 5:
2025					echo "<p>Updating post table (2/2)...</p>";
2026					flush();
2027
2028					$table = 'posts';
2029					$column = 'ipaddress';
2030					break;
2031				case 4:
2032					echo "<p>Updating moderatorlog table...</p>";
2033					flush();
2034
2035					$table = 'moderatorlog';
2036					$column = 'ipaddress';
2037					break;
2038				case 3:
2039					echo "<p>Updating maillog table...</p>";
2040					flush();
2041
2042					$table = 'maillogs';
2043					$column = 'ipaddress';
2044					break;
2045				case 2:
2046					echo "<p>Updating adminsession table...</p>";
2047					flush();
2048
2049					$table = 'adminsessions';
2050					$column = 'ip';
2051					// Skip conversion
2052					$db->delete_query('adminsessions');
2053					break;
2054				default:
2055					echo "<p>Updating adminlog table...</p>";
2056					flush();
2057
2058					$mybb->input['iptable'] = 1;
2059					$table = 'adminlog';
2060					$column = 'ipaddress';
2061					break;
2062			}
2063			// Truncate invalid IPs
2064			$db->write_query("UPDATE ".TABLE_PREFIX."{$table} SET {$column} = SUBSTR({$column}, 16) WHERE LENGTH({$column})>16");
2065			switch($db->type)
2066			{
2067				case "pgsql":
2068					// Drop default value before converting the column
2069					$db->modify_column($table, $column, false, false);
2070					$db->modify_column($table, $column, "bytea USING {$column}::bytea", 'set', "''");
2071					break;
2072				case "sqlite":
2073					$db->modify_column($table, $column, "blob(16) NOT NULL default ''");
2074					break;
2075				default:
2076					$db->modify_column($table, $column, "varbinary(16) NOT NULL default ''");
2077					break;
2078			}
2079			if($mybb->input['iptable'] < 10)
2080			{
2081				$iptable = "<input type=\"hidden\" name=\"iptable\" value=\"".($mybb->input['iptable']+1)."\" />";
2082			}
2083			break;
2084		case 3:
2085			echo "<p>Updating user table (2/4)...</p>";
2086			flush();
2087
2088			if($db->field_exists('longlastip', 'users'))
2089			{
2090				// This may take a while
2091				$db->drop_column("users", "longlastip");
2092			}
2093			$next_task = 4;
2094			break;
2095		case 2:
2096			echo "<p>Updating user table (1/4)...</p>";
2097			flush();
2098
2099			if($db->field_exists('longregip', 'users'))
2100			{
2101				// This may take a while
2102				$db->drop_column("users", "longregip");
2103			}
2104			$next_task = 3;
2105			break;
2106		default:
2107			echo "<p>Updating post table (1/2)...</p>";
2108			flush();
2109
2110			if($db->field_exists('longipaddress', 'posts'))
2111			{
2112				// This may take a while
2113				$db->drop_column("posts", "longipaddress");
2114			}
2115			$next_task = 2;
2116			break;
2117	}
2118
2119	if($next_task == 9)
2120	{
2121		$contents = "<p>Click next to continue with the upgrade process.</p>";
2122		$nextact = "30_updatetheme";
2123	}
2124	else
2125	{
2126		$contents = "<p><input type=\"hidden\" name=\"iptask\" value=\"{$next_task}\" />{$iptable}{$ipstart}Done. Click Next to continue the IP conversion.</p>";
2127
2128		global $footer_extra;
2129		$footer_extra = "<script type=\"text/javascript\">$(function() { var button = $('.submit_button'); if(button) { button.val('Automatically Redirecting...'); button.prop('disabled', true); button.css('color', '#aaa'); button.css('border-color', '#aaa'); document.forms[0].submit(); } });</script>";
2130		$nextact = "30_dbchanges_ip";
2131	}
2132
2133	$output->print_contents($contents);
2134
2135	$output->print_footer($nextact);
2136}
2137
2138function upgrade30_updatetheme()
2139{
2140	global $db, $mybb, $output, $config;
2141
2142	if(file_exists(MYBB_ROOT.$mybb->config['admin_dir']."/inc/functions_themes.php"))
2143	{
2144		require_once MYBB_ROOT.$mybb->config['admin_dir']."/inc/functions_themes.php";
2145	}
2146	else if(file_exists(MYBB_ROOT."admin/inc/functions_themes.php"))
2147	{
2148		require_once MYBB_ROOT."admin/inc/functions_themes.php";
2149	}
2150	else
2151	{
2152		$output->print_error("Please make sure your admin directory is uploaded correctly.");
2153	}
2154
2155	$output->print_header("Updating Themes");
2156
2157	// New default user star
2158	$contents = "<p>Updating the Default user star image... ";
2159	$db->update_query("usergroups", array('starimage' => 'images/star.png'), "starimage='images/star.gif'");
2160	$contents .= "done.</p>";
2161
2162	$contents .= "<p>Adding new stylesheets... ";
2163
2164	$query = $db->simple_select("themes", "*", "tid='1'");
2165
2166	$theme = $db->fetch_array($query);
2167	$properties = my_unserialize($theme['properties']);
2168	$stylesheets = my_unserialize($theme['stylesheets']);
2169
2170	$old = array("global.css", "usercp.css", "modcp.css", "star_ratings.css");
2171	$colors = @file_get_contents(INSTALL_ROOT.'resources/mybb_theme.xml');
2172	$parser = create_xml_parser($colors);
2173	$tree = $parser->get_tree();
2174
2175	if(is_array($tree) && is_array($tree['theme']))
2176	{
2177		if(is_array($tree['theme']['stylesheets']))
2178		{
2179			foreach($tree['theme']['stylesheets']['stylesheet'] as $stylesheet)
2180			{
2181				$new_stylesheet = array(
2182					"name" => $db->escape_string($stylesheet['attributes']['name']),
2183					"tid" => 1,
2184					"attachedto" => $db->escape_string($stylesheet['attributes']['attachedto']),
2185					"stylesheet" => $db->escape_string($stylesheet['value']),
2186					"lastmodified" => TIME_NOW,
2187					"cachefile" => $db->escape_string($stylesheet['attributes']['name'])
2188				);
2189
2190				if(in_array($new_stylesheet['name'], $old))
2191				{
2192					// We can update the disporder here
2193					$properties['disporder'][$stylesheet['attributes']['name']] = $stylesheet['attributes']['disporder'];
2194				}
2195				else
2196				{
2197					// Insert new stylesheet
2198					$sid = $db->insert_query("themestylesheets", $new_stylesheet);
2199					$css_url = "css.php?stylesheet={$sid}";
2200
2201					$cached = cache_stylesheet(1, $stylesheet['attributes']['name'], $stylesheet['value']);
2202
2203					if($cached)
2204					{
2205						$css_url = $cached;
2206					}
2207
2208					// Add to display and stylesheet list
2209					$properties['disporder'][$stylesheet['attributes']['name']] = $stylesheet['attributes']['disporder'];
2210					$attachedto = $stylesheet['attributes']['attachedto'];
2211					if(!$attachedto)
2212					{
2213						$attachedto = "global";
2214					}
2215
2216					// private.php?compose,folders|usercp.php,global|global
2217					$attachedto = explode("|", $attachedto);
2218					foreach($attachedto as $attached_file)
2219					{
2220						$attached_actions = explode(",", $attached_file);
2221						$attached_file = array_shift($attached_actions);
2222						if(count($attached_actions) == 0)
2223						{
2224							$attached_actions = array("global");
2225						}
2226
2227						foreach($attached_actions as $action)
2228						{
2229							$stylesheets[$attached_file][$action][] = $css_url;
2230						}
2231					}
2232				}
2233			}
2234		}
2235	}
2236
2237	$update_array = array(
2238		"properties" => $db->escape_string(my_serialize($properties)),
2239		"stylesheets" => $db->escape_string(my_serialize($stylesheets))
2240	);
2241
2242	$db->update_query("themes", $update_array, "tid = '1'");
2243
2244	$contents .= "done.</p>";
2245
2246	$contents .= "<p>Adding a disporder to all stylesheets... ";
2247
2248	$query = $db->simple_select("themes", "tid,properties,stylesheets");
2249	while($theme = $db->fetch_array($query))
2250	{
2251		$properties = my_unserialize($theme['properties']);
2252		$stylesheets = my_unserialize($theme['stylesheets']);
2253
2254		// Disporder already set?
2255		if(isset($properties['disporder']) && !empty($properties['disporder']))
2256		{
2257			continue;
2258		}
2259
2260		$disporder = 1;
2261
2262		// First go through all own stylesheets
2263		$query2 = $db->simple_select("themestylesheets", "name", "tid='{$theme['tid']}'");
2264		while($name = $db->fetch_field($query2, "name"))
2265		{
2266			$properties['disporder'][$name] = $disporder;
2267			$disporder++;
2268		}
2269
2270		// Next go through the inherited stylesheets
2271		if(!empty($stylesheets))
2272		{
2273			foreach($stylesheets as $a)
2274			{
2275				foreach($a as $file => $stylesheet)
2276				{
2277					// Don't ask me... Throws an error otherwise
2278					if(empty($stylesheet))
2279					{
2280						continue;
2281					}
2282					foreach($stylesheet as $s)
2283					{
2284						$name = pathinfo($s, PATHINFO_BASENAME);
2285						if(empty($properties['disporder']) || !in_array($name, array_keys($properties['disporder'])))
2286						{
2287							$properties['disporder'][$name] = $disporder;
2288							$disporder++;
2289						}
2290					}
2291				}
2292			}
2293		}
2294
2295		$db->update_query("themes", array("properties" => $db->escape_string(my_serialize($properties))), "tid='{$theme['tid']}'");
2296	}
2297
2298	$contents .= "done.</p>";
2299
2300	$contents .= "<p>Adding the Default colors... ";
2301
2302	$query = $db->simple_select("themes", "*", "tid = '2'");
2303
2304	// Someone deleted the default theme... :o
2305	if($db->num_rows($query) != 0)
2306	{
2307		$theme = $db->fetch_array($query);
2308		$properties = my_unserialize($theme['properties']);
2309		$stylesheets = my_unserialize($theme['stylesheets']);
2310
2311		$properties['editortheme'] = "mybb.css"; // New editor, so reset the theme for it
2312		$properties['tablespace'] = 5;
2313		$properties['borderwidth'] = 0;
2314		// Reset the logo if it's still the default one
2315		if($properties['logo'] == "images/logo.gif")
2316		{
2317			$properties['logo'] = "images/logo.png";
2318		}
2319
2320		$colors = @file_get_contents(INSTALL_ROOT.'resources/mybb_theme_colors.xml');
2321		$parser = create_xml_parser($colors);
2322		$tree = $parser->get_tree();
2323
2324		if(is_array($tree) && is_array($tree['colors']))
2325		{
2326			if(is_array($tree['colors']['scheme']))
2327			{
2328				foreach($tree['colors']['scheme'] as $tag => $value)
2329				{
2330					$exp = explode("=", $value['value']);
2331
2332					$properties['colors'][$exp[0]] = $exp[1];
2333				}
2334			}
2335
2336			if(is_array($tree['colors']['stylesheets']))
2337			{
2338				$count = count($properties['disporder']) + 1;
2339				foreach($tree['colors']['stylesheets']['stylesheet'] as $stylesheet)
2340				{
2341					$new_stylesheet = array(
2342						"name" => $db->escape_string($stylesheet['attributes']['name']),
2343						"tid" => 2,
2344						"attachedto" => $db->escape_string($stylesheet['attributes']['attachedto']),
2345						"stylesheet" => $db->escape_string($stylesheet['value']),
2346						"lastmodified" => TIME_NOW,
2347						"cachefile" => $db->escape_string($stylesheet['attributes']['name'])
2348					);
2349
2350					$sid = $db->insert_query("themestylesheets", $new_stylesheet);
2351					$css_url = "css.php?stylesheet={$sid}";
2352
2353					$cached = cache_stylesheet($tid, $stylesheet['attributes']['name'], $stylesheet['value']);
2354
2355					if($cached)
2356					{
2357						$css_url = $cached;
2358					}
2359
2360					// Add to display and stylesheet list
2361					$properties['disporder'][$stylesheet['attributes']['name']] = $count;
2362					$stylesheets[$stylesheet['attributes']['attachedto']]['global'][] = $css_url;
2363
2364					++$count;
2365				}
2366			}
2367
2368			$update_array = array(
2369				"properties" => $db->escape_string(my_serialize($properties)),
2370				"stylesheets" => $db->escape_string(my_serialize($stylesheets))
2371			);
2372
2373			$db->update_query("themes", $update_array, "tid = '2'");
2374		}
2375	}
2376
2377	$contents .= "done.</p>";
2378
2379	$contents .= '<p>Re-caching and minifying existing stylesheets...</p>';
2380
2381	$num_re_cached = recache_existing_styles();
2382
2383	$contents .= "Done. {$num_re_cached} stylesheets re-cached.";
2384
2385	echo $contents;
2386
2387	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
2388
2389	if(!isset($config['secret_pin']) && is_writable(MYBB_ROOT."inc/config.php"))
2390	{
2391		$output->print_footer("30_acppin");
2392	}
2393	else
2394	{
2395		$output->print_footer("30_done");
2396	}
2397}
2398
2399function upgrade30_acppin()
2400{
2401	global $config, $output;
2402
2403	$output->print_header("Add an ACP PIN");
2404
2405	echo "<p>We added a new security function in 1.8: The possibility to set a security PIN which you need to enter the ACP.<br />\n";
2406	echo "If you don't want to set a PIN you can simply skip this step (leave the field below empty). You can still set the PIN later (see the docs to see how).</p>\n";
2407	echo '<div class="border_wrapper">
2408			<div class="title">ACP PIN Configuration</div>
2409			<table class="general" cellspacing="0">
2410				<tbody>
2411				<tr>
2412					<th colspan="2" class="first last">ACP Security PIN</th>
2413				</tr>
2414				<tr class="first">
2415					<td class="first"><label for="bbname">PIN:</label></td>
2416					<td class="last alt_col"><input type="password" class="text_input" name="pin" id="pin" value="'.$config['secret_pin'].'" /></td>
2417				</tr>
2418				</tbody>
2419			</table>
2420		</div>';
2421
2422	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
2423
2424	$output->print_footer("30_acppin_submit");
2425}
2426
2427function upgrade30_acppin_submit()
2428{
2429	global $db, $mybb, $output, $config;
2430
2431	$output->print_header("Writing the config file");
2432
2433	$content = "<p>We're now writing your PIN (if you've entered one) to the config.php file... ";
2434
2435	if(!is_writable(MYBB_ROOT."inc/config.php"))
2436	{
2437		$content .= "Failed (config.php not writable)";
2438	}
2439	else if(isset($config['secret_pin']))
2440	{
2441		$content .= "Skipped (PIN already set)";
2442	}
2443	else
2444	{
2445		$pin = addslashes($mybb->get_input('pin'));
2446
2447		$file = @fopen(MYBB_ROOT."inc/config.php", "r+");
2448
2449		$contents = '';
2450		while(!@feof($file))
2451		{
2452			$contents .= @fread($file, 8436);
2453		}
2454
2455		$contents_temp = str_replace(array("\r", "\t", "\n", " ", "\0", "\x0B"), '', $contents);
2456
2457		// Set the pointer before the closing php tag to remove it
2458		$pos = strrpos($contents, "?>");
2459		if(my_substr($contents_temp, -2) == "?>")
2460		{
2461			@fseek($file, $pos, SEEK_SET);
2462		}
2463
2464		@fwrite($file, "
2465/**
2466 * Admin CP Secret PIN
2467 *  If you wish to request a PIN
2468 *  when someone tries to login
2469 *  on your Admin CP, enter it below.
2470 */
2471
2472\$config['secret_pin'] = '{$pin}';");
2473
2474		@fclose($file);
2475
2476		$content .= "Done";
2477	}
2478
2479	echo $content."</p>";
2480
2481	$output->print_contents("<p>Click next to continue with the upgrade process.</p>");
2482
2483	$output->print_footer("30_done");
2484}
2485
2486/**
2487 * Re-cache the existing stylesheets so that they get minified.
2488 *
2489 * @return int The number of re-cached stylesheets.
2490 */
2491function recache_existing_styles()
2492{
2493	global $db;
2494
2495	$query = $db->simple_select('themestylesheets', '*');
2496
2497	$num_updated = 0;
2498
2499	while($stylesheet = $db->fetch_array($query))
2500	{
2501		if (cache_stylesheet((int) $stylesheet['tid'], $stylesheet['name'], $stylesheet['stylesheet']))
2502		{
2503			++$num_updated;
2504		}
2505	}
2506
2507	return $num_updated;
2508}
2509