~azzar1/unity/add-show-desktop-key

443 by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0
1
<?php
2
/**
3
*
4
* @package install
5
* @version $Id: functions_convert.php,v 1.68 2007/10/14 12:31:32 kellanved Exp $
6
* @copyright (c) 2006 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
*
9
*/
10
11
/**
12
* @ignore
13
*/
14
if (!defined('IN_PHPBB'))
15
{
16
	exit;
17
}
18
19
/**
20
* Default avatar width/height
21
* @ignore
22
*/
23
define('DEFAULT_AVATAR_X', 80);
24
define('DEFAULT_AVATAR_Y', 80);
25
26
// Global functions - all functions can be used by convertors
27
28
// SIMPLE FUNCTIONS
29
30
/**
31
* Return the preceding value
32
*/
33
function dec($var)
34
{
35
	return --$var;
36
}
37
38
/**
39
* Return the next value
40
*/
41
function inc($var)
42
{
43
	return ++$var;
44
}
45
46
/**
47
* Return whether the value is positive
48
*/
49
function is_positive($n)
50
{
51
	return ($n > 0) ? 1 : 0;
52
}
53
54
/**
55
* Boolean inverse of the value
56
*/
57
function not($var)
58
{
59
	return ($var) ? 0 : 1;
60
}
61
62
/**
63
* Convert a textual value to it's equivalent boolean value
64
*
65
* @param string $str String to convert (converts yes, on, y, 1 and true to boolean true)
66
* @return boolean The equivalent value
67
*/
68
function str_to_bool($str)
69
{
70
	$str = strtolower($str);
71
	return ($str == 'yes' || $str == 'on' || $str == 'y' || $str == 'true' || $str == '1') ? true : false;
72
}
73
74
/**
75
* Function to mimic php's empty() function (it is the same)
76
*/
77
function is_empty($mixed)
78
{
79
	return empty($mixed);
80
}
81
82
/**
83
* Convert the name of a user's primary group to the appropriate equivalent phpBB group id
84
*
85
* @param string $status The name of the group
86
* @return int The group_id corresponding to the equivalent group
87
*/
88
function str_to_primary_group($status)
89
{
90
	switch (ucfirst(strtolower($status)))
91
	{
92
		case 'Administrator':
93
			return get_group_id('administrators');
94
		break;
95
96
		case 'Super moderator':
97
		case 'Global moderator':
98
		case 'Moderator':
99
			return get_group_id('global_moderators');
100
		break;
101
102
		case 'Guest':
103
		case 'Anonymous':
104
			return get_group_id('guests');
105
		break;
106
107
		default:
108
			return get_group_id('registered');
109
		break;
110
	}
111
}
112
113
/**
114
* Convert a boolean into the appropriate phpBB constant indicating whether the item is locked
115
*/
116
function is_item_locked($bool)
117
{
118
	return ($bool) ? ITEM_LOCKED : ITEM_UNLOCKED;
119
}
120
121
/**
122
* Convert a value from days to seconds
123
*/
124
function days_to_seconds($days)
125
{
126
	return ($days * 86400);
127
}
128
129
/**
130
* Determine whether a user is anonymous and return the appropriate new user_id
131
*/
132
function is_user_anonymous($user_id)
133
{
134
	return ($user_id > ANONYMOUS) ? $user_id : ANONYMOUS;
135
}
136
137
/**
138
* Generate a key value based on existing values
139
*
140
* @param int $pad Amount to add to the maximum value
141
* @return int Key value
142
*/
143
function auto_id($pad = 0)
144
{
145
	global $auto_id, $convert_row;
146
147
	if (!empty($convert_row['max_id']))
148
	{
149
		return $convert_row['max_id'] + $pad;
150
	}
151
	
152
	return $auto_id + $pad;
153
}
154
155
/**
156
* Convert a boolean into the appropriate phpBB constant indicating whether the user is active
157
*/
158
function set_user_type($user_active)
159
{
160
	return ($user_active) ? USER_NORMAL : USER_INACTIVE;
161
}
162
163
/**
164
* Convert a value from minutes to hours
165
*/
166
function minutes_to_hours($minutes)
167
{
168
	return ($minutes / 3600);
169
}
170
171
/**
172
* Return the group_id for a given group name
173
*/
174
function get_group_id($group_name)
175
{
176
	global $db, $group_mapping;
177
178
	if (empty($group_mapping))
179
	{
180
		$sql = 'SELECT group_name, group_id
181
			FROM ' . GROUPS_TABLE;
182
		$result = $db->sql_query($sql);
183
184
		$group_mapping = array();
185
		while ($row = $db->sql_fetchrow($result))
186
		{
187
			$group_mapping[strtoupper($row['group_name'])] = (int) $row['group_id'];
188
		}
189
		$db->sql_freeresult($result);
190
	}
191
192
	if (!sizeof($group_mapping))
193
	{
194
		add_default_groups();
195
		return get_group_id($group_name);
196
	}
197
198
	if (isset($group_mapping[strtoupper($group_name)]))
199
	{
200
		return $group_mapping[strtoupper($group_name)];
201
	}
202
203
	return $group_mapping['REGISTERED'];
204
}
205
206
/**
207
* Generate the email hash stored in the users table
208
*/
209
function gen_email_hash($email)
210
{
211
	return (crc32(strtolower($email)) . strlen($email));
212
}
213
214
/**
215
* Convert a boolean into the appropriate phpBB constant indicating whether the topic is locked
216
*/
217
function is_topic_locked($bool)
218
{
219
	return (!empty($bool)) ? ITEM_LOCKED : ITEM_UNLOCKED;
220
}
221
222
/**
223
* Generate a bbcode_uid value
224
*/
225
function make_uid($timestamp)
226
{
227
	static $last_timestamp, $last_uid;
228
229
	if (empty($last_timestamp) || $timestamp != $last_timestamp)
230
	{
231
		$last_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);
232
	}
233
	$last_timestamp = $timestamp;
234
	return $last_uid;
235
}
236
237
238
/**
239
* Validate a website address
240
*/
241
function validate_website($url)
242
{
243
	if ($url === 'http://')
244
	{
245
		return '';
246
	}
247
	else if (!preg_match('#^[a-z0-9]+://#i', $url) && strlen($url) > 0)
248
	{
249
		return 'http://' . $url;
250
	}
251
	return $url;
252
}
253
254
/**
255
* Convert nulls to zeros for fields which allowed a NULL value in the source but not the destination
256
*/
257
function null_to_zero($value)
258
{
259
	return ($value === NULL) ? 0 : $value;
260
}
261
262
/**
263
* Convert nulls to empty strings for fields which allowed a NULL value in the source but not the destination
264
*/
265
function null_to_str($value)
266
{
267
	return ($value === NULL) ? '' : $value;
268
}
269
270
// EXTENDED FUNCTIONS
271
272
/**
273
* Get old config value
274
*/
275
function get_config_value($config_name)
276
{
277
	static $convert_config;
278
279
	if (!isset($convert_config))
280
	{
281
		$convert_config = get_config();
282
	}
283
	
284
	if (!isset($convert_config[$config_name]))
285
	{
286
		return false;
287
	}
288
289
	return (empty($convert_config[$config_name])) ? '' : $convert_config[$config_name];
290
}
291
292
/**
293
* Convert an IP address from the hexadecimal notation to normal dotted-quad notation
294
*/
295
function decode_ip($int_ip)
296
{
297
	if (!$int_ip)
298
	{
299
		return $int_ip;
300
	}
301
302
	$hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
303
304
	// Any mod changing the way ips are stored? Then we are not able to convert and enter the ip "as is" to not "destroy" anything...
305
	if (sizeof($hexipbang) < 4)
306
	{
307
		return $int_ip;
308
	}
309
310
	return hexdec($hexipbang[0]) . '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
311
}
312
313
/**
314
* Reverse the encoding of wild-carded bans
315
*/
316
function decode_ban_ip($int_ip)
317
{
318
	return str_replace('255', '*', decode_ip($int_ip));
319
}
320
321
/**
322
* Determine the MIME-type of a specified filename
323
* This does not actually inspect the file, but simply uses the file extension
324
*/
325
function mimetype($filename)
326
{
327
	if (!preg_match('/\.([a-z0-9]+)$/i', $filename, $m))
328
	{
329
		return 'application/octet-stream';
330
	}
331
332
	switch (strtolower($m[1]))
333
	{
334
		case 'zip':		return 'application/zip';
335
		case 'jpeg':	return 'image/jpeg';
336
		case 'jpg':		return 'image/jpeg';
337
		case 'jpe':		return 'image/jpeg';
338
		case 'png':		return 'image/png';
339
		case 'gif':		return 'image/gif';
340
		case 'htm':
341
		case 'html':	return 'text/html';
342
		case 'tif':		return 'image/tiff';
343
		case 'tiff':	return 'image/tiff';
344
		case 'ras':		return 'image/x-cmu-raster';
345
		case 'pnm':		return 'image/x-portable-anymap';
346
		case 'pbm':		return 'image/x-portable-bitmap';
347
		case 'pgm':		return 'image/x-portable-graymap';
348
		case 'ppm':		return 'image/x-portable-pixmap';
349
		case 'rgb':		return 'image/x-rgb';
350
		case 'xbm':		return 'image/x-xbitmap';
351
		case 'xpm':		return 'image/x-xpixmap';
352
		case 'xwd':		return 'image/x-xwindowdump';
353
		case 'z':		return 'application/x-compress';
354
		case 'gtar':	return 'application/x-gtar';
355
		case 'tgz':		return 'application/x-gtar';
356
		case 'gz':		return 'application/x-gzip';
357
		case 'tar':		return 'application/x-tar';
358
		case 'xls':		return 'application/excel';
359
		case 'pdf':		return 'application/pdf';
360
		case 'ppt':		return 'application/powerpoint';
361
		case 'rm':		return 'application/vnd.rn-realmedia';
362
		case 'wma':		return 'audio/x-ms-wma';
363
		case 'swf':		return 'application/x-shockwave-flash';
364
		case 'ief':		return 'image/ief';
365
		case 'doc':
366
		case 'dot':
367
		case 'wrd':		return 'application/msword';
368
		case 'ai':
369
		case 'eps':
370
		case 'ps':		return 'application/postscript';
371
		case 'asc':
372
		case 'txt':
373
		case 'c':
374
		case 'cc':
375
		case 'h':
376
		case 'hh':
377
		case 'cpp':
378
		case 'hpp':
379
		case 'php':
380
		case 'php3':	return 'text/plain';
381
		default: 		return 'application/octet-stream';
382
	}
383
}
384
385
/**
386
* Obtain the dimensions of all remotely hosted avatars
387
* This should only be called from execute_last
388
* There can be significant network overhead if there are a large number of remote avatars
389
* @todo Look at the option of allowing the user to decide whether this is called or to force the dimensions
390
*/
391
function remote_avatar_dims()
392
{
393
	global $db;
394
395
	$sql = 'SELECT user_id, user_avatar
396
		FROM ' . USERS_TABLE . '
397
		WHERE user_avatar_type = ' . AVATAR_REMOTE;
398
	$result = $db->sql_query($sql);
399
400
	$remote_avatars = array();
401
	while ($row = $db->sql_fetchrow($result))
402
	{
403
		$remote_avatars[(int) $row['user_id']] = $row['user_avatar'];
404
	}
405
	$db->sql_freeresult($result);
406
407
	foreach ($remote_avatars as $user_id => $avatar)
408
	{
409
		$width = (int) get_remote_avatar_dim($avatar, 0);
410
		$height = (int) get_remote_avatar_dim($avatar, 1);
411
412
		$sql = 'UPDATE ' . USERS_TABLE . '
413
			SET user_avatar_width = ' . (int) $width . ', user_avatar_height = ' . (int) $height . '
414
			WHERE user_id = ' . $user_id;
415
		$db->sql_query($sql);
416
	}
417
}
418
419
function import_avatar_gallery($gallery_name = '', $subdirs_as_galleries = false)
420
{
421
	global $config, $convert, $phpbb_root_path, $user;
422
423
	$relative_path = empty($convert->convertor['source_path_absolute']);
424
425
	if (empty($convert->convertor['avatar_gallery_path']))
426
	{
427
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'import_avatar_gallery()'), __LINE__, __FILE__);
428
	}
429
430
	$src_path = relative_base(path($convert->convertor['avatar_gallery_path'], $relative_path), $relative_path);
431
432
	if (is_dir($src_path))
433
	{
434
		// Do not die on failure... safe mode restrictions may be in effect.
435
		copy_dir($convert->convertor['avatar_gallery_path'], path($config['avatar_gallery_path']) . $gallery_name, !$subdirs_as_galleries, false, false, $relative_path);
436
437
		// only doing 1 level deep. (ibf 1.x)
438
		// notes: ibf has 2 tiers: directly in the avatar directory for base gallery (handled in the above statement), plus subdirs(handled below).
439
		// recursive subdirs ignored. -- i don't know if other forums support recursive galleries. if they do, this following code could be upgraded to be recursive.
440
		if ($subdirs_as_galleries)
441
		{
442
			$dirlist = array();
443
			if ($handle = @opendir($src_path))
444
			{
445
				while ($entry = readdir($handle))
446
				{
447
					if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
448
					{
449
						continue;
450
					}
451
452
					if (is_dir($src_path . $entry))
453
					{
454
						$dirlist[] = $entry;
455
					}
456
				}
457
				closedir($handle);
458
			}
459
			else if ($dir = @dir($src_path))
460
			{
461
				while ($entry = $dir->read())
462
				{
463
					if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
464
					{
465
						continue;
466
					}
467
468
					if (is_dir($src_path . $entry))
469
					{
470
						$dirlist[] = $entry;
471
					}
472
				}
473
				$dir->close();
474
			}
475
476
			for ($i = 0; $i < sizeof($dirlist); ++$i)
477
			{
478
				$dir = $dirlist[$i];
479
480
				// Do not die on failure... safe mode restrictions may be in effect.
481
				copy_dir(path($convert->convertor['avatar_gallery_path'], $relative_path) . $dir, path($config['avatar_gallery_path']) . $dir, true, false, false, $relative_path);
482
			}
483
		}
484
	}
485
}
486
487
function import_attachment_files($category_name = '')
488
{
489
	global $config, $convert, $phpbb_root_path, $db, $user;
490
491
	$sql = 'SELECT config_value AS upload_path
492
		FROM ' . CONFIG_TABLE . "
493
		WHERE config_name = 'upload_path'";
494
	$result = $db->sql_query($sql);
495
	$config['upload_path'] = $db->sql_fetchfield('upload_path');
496
	$db->sql_freeresult($result);
497
498
	$relative_path = empty($convert->convertor['source_path_absolute']);
499
500
	if (empty($convert->convertor['upload_path']))
501
	{
502
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment_files()'), __LINE__, __FILE__);
503
	}
504
505
	if (is_dir(relative_base(path($convert->convertor['upload_path'], $relative_path), $relative_path)))
506
	{
507
		copy_dir($convert->convertor['upload_path'], path($config['upload_path']) . $category_name, true, false, true, $relative_path);
508
	}
509
}
510
511
function attachment_forum_perms($forum_id)
512
{
513
	if (!is_array($forum_id))
514
	{
515
		$forum_id = array($forum_id);
516
	}
517
518
	return serialize($forum_id);
519
}
520
521
// base64todec function
522
// -> from php manual?
523
function base64_unpack($string)
524
{
525
	$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-';
526
	$base = strlen($chars);
527
528
	$length = strlen($string);
529
	$number = 0;
530
531
	for ($i = 1; $i <= $length; $i++)
532
	{
533
		$pos = $length - $i;
534
		$operand = strpos($chars, substr($string, $pos, 1));
535
		$exponent = pow($base, $i-1);
536
		$dec_value = $operand * $exponent;
537
		$number += $dec_value;
538
	}
539
540
	return $number;
541
}
542
543
function _import_check($config_var, $source, $use_target)
544
{
545
	global $convert, $config;
546
547
	$result = array(
548
		'orig_source'	=> $source,
549
		'copied'		=> false,
550
		'relative_path'	=> (empty($convert->convertor['source_path_absolute'])) ? true : false,
551
	);
552
553
	// copy file will prepend $phpBB_root_path
554
	$target = $config[$config_var] . '/' . basename(($use_target === false) ? $source : $use_target);
555
556
	if (!empty($convert->convertor[$config_var]) && strpos($source, $convert->convertor[$config_var]) !== 0)
557
	{
558
		$source = $convert->convertor[$config_var] . $source;
559
	}
560
561
	$result['source'] = $source;
562
563
	if (file_exists(relative_base($source, $result['relative_path'], __LINE__, __FILE__)))
564
	{
565
		$result['copied'] = copy_file($source, $target, false, false, $result['relative_path']);
566
	}
567
568
	if ($result['copied'])
569
	{
570
		$result['target'] = basename($target);
571
	}
572
	else
573
	{
574
		$result['target'] = ($use_target !== false) ? $result['orig_source'] : basename($target);
575
	}
576
577
	return $result;
578
}
579
580
function import_attachment($source, $use_target = false)
581
{
582
	if (empty($source))
583
	{
584
		return '';
585
	}
586
587
	global $convert, $phpbb_root_path, $config, $user;
588
589
	if (empty($convert->convertor['upload_path']))
590
	{
591
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment()'), __LINE__, __FILE__);
592
	}
593
594
	$result = _import_check('upload_path', $source, $use_target);
595
596
	if ($result['copied'])
597
	{
598
		// Thumbnails?
599
		if (is_array($convert->convertor['thumbnails']))
600
		{
601
			$thumb_dir = $convert->convertor['thumbnails'][0];
602
			$thumb_prefix = $convert->convertor['thumbnails'][1];
603
			$thumb_source = $thumb_dir . $thumb_prefix . basename($result['source']);
604
605
			if (strpos($thumb_source, $convert->convertor['upload_path']) !== 0)
606
			{
607
				$thumb_source = $convert->convertor['upload_path'] . $thumb_source;
608
			}
609
			$thumb_target = $config['upload_path'] . '/thumb_' . $result['target'];
610
611
			if (file_exists(relative_base($thumb_source, $result['relative_path'], __LINE__, __FILE__)))
612
			{
613
				copy_file($thumb_source, $thumb_target, false, false, $result['relative_path']);
614
			}
615
		}
616
	}
617
618
	return $result['target'];
619
}
620
621
function import_rank($source, $use_target = false)
622
{
623
	if (empty($source))
624
	{
625
		return '';
626
	}
627
628
	global $convert, $phpbb_root_path, $config, $user;
629
630
	if (!isset($convert->convertor['ranks_path']))
631
	{
632
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_RANKS_PATH'], 'import_rank()'), __LINE__, __FILE__);
633
	}
634
635
	$result = _import_check('ranks_path', $source, $use_target);
636
	return $result['target'];
637
}
638
639
function import_smiley($source, $use_target = false)
640
{
641
	if (empty($source))
642
	{
643
		return '';
644
	}
645
646
	global $convert, $phpbb_root_path, $config, $user;
647
648
	if (!isset($convert->convertor['smilies_path']))
649
	{
650
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'import_smiley()'), __LINE__, __FILE__);
651
	}
652
653
	$result = _import_check('smilies_path', $source, $use_target);
654
	return $result['target'];
655
}
656
657
/*
658
*/
659
function import_avatar($source, $use_target = false, $user_id = false)
660
{
661
	if (empty($source) || preg_match('#^https?:#i', $source) || preg_match('#blank\.(gif|png)$#i', $source))
662
	{
663
		return;
664
	}
665
666
	global $convert, $phpbb_root_path, $config, $user;
667
668
	if (!isset($convert->convertor['avatar_path']))
669
	{
670
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'import_avatar()'), __LINE__, __FILE__);
671
	}
672
	
673
	if ($use_target === false && $user_id !== false)
674
	{
675
		$use_target = $config['avatar_salt'] . '_' . $user_id . '.' . substr(strrchr($source, '.'), 1);
676
	}
677
	
678
	$result = _import_check('avatar_path', $source, $use_target);
679
680
	return ((!empty($user_id)) ? $user_id : $use_target) . '.' . substr(strrchr($source, '.'), 1);
681
}
682
683
/**
684
* @todo all image dimension functions below (there are a *lot*) should get revisited and converted to one or two functions (no more needed, really).
685
*/
686
687
/**
688
* Calculate the size of the specified image
689
* Called from the following functions for calculating the size of specific image types
690
*/
691
function get_image_dim($source)
692
{
693
	if (empty($source))
694
	{
695
		return array(0, 0);
696
	}
697
698
	global $convert;
699
700
	$relative_path = empty($convert->convertor['source_path_absolute']);
701
702
	if (file_exists(relative_base($source, $relative_path)))
703
	{
704
		$image = relative_base($source, $relative_path);
705
		return @getimagesize($image);
706
	}
707
708
	return false;
709
}
710
711
/**
712
* Obtain the width of the specified smilie
713
*/
714
function get_smiley_width($src)
715
{
716
	return get_smiley_dim($src, 0);
717
}
718
719
/**
720
* Obtain the height of the specified smilie
721
*/
722
function get_smiley_height($src)
723
{
724
	return get_smiley_dim($src, 1);
725
}
726
727
/**
728
* Obtain the size of the specified smilie (using the cache if possible) and cache the value
729
*/
730
function get_smiley_dim($source, $axis)
731
{
732
	if (empty($source))
733
	{
734
		return 15;
735
	}
736
737
	static $smiley_cache = array();
738
739
	if (isset($smiley_cache[$source]))
740
	{
741
		return $smiley_cache[$source][$axis];
742
	}
743
744
	global $convert, $phpbb_root_path, $config, $user;
745
746
	$orig_source = $source;
747
748
	if (!isset($convert->convertor['smilies_path']))
749
	{
750
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'get_smiley_dim()'), __LINE__, __FILE__);
751
	}
752
753
	if (!empty($convert->convertor['smilies_path']) && strpos($source, $convert->convertor['smilies_path']) !== 0)
754
	{
755
		$source = $convert->convertor['smilies_path'] . $source;
756
	}
757
758
	$smiley_cache[$orig_source] = get_image_dim($source);
759
760
	if (empty($smiley_cache[$orig_source]) || empty($smiley_cache[$orig_source][0]) || empty($smiley_cache[$orig_source][1]))
761
	{
762
		$smiley_cache[$orig_source] = array(15, 15);
763
		return 15;
764
	}
765
766
	return $smiley_cache[$orig_source][$axis];
767
}
768
769
/**
770
* Obtain the width of the specified avatar
771
*/
772
function get_avatar_width($src, $func = false, $arg1 = false, $arg2 = false)
773
{
774
	return get_avatar_dim($src, 0, $func, $arg1, $arg2);
775
}
776
777
/**
778
* Obtain the height of the specified avatar
779
*/
780
function get_avatar_height($src, $func = false, $arg1 = false, $arg2 = false)
781
{
782
	return get_avatar_dim($src, 1, $func, $arg1, $arg2);
783
}
784
785
/**
786
*/
787
function get_avatar_dim($src, $axis, $func = false, $arg1 = false, $arg2 = false)
788
{
789
	$avatar_type = AVATAR_UPLOAD;
790
791
	if ($func)
792
	{
793
		if ($arg1 || $arg2)
794
		{
795
			$ary = array($arg1);
796
797
			if ($arg2)
798
			{
799
				$ary[] = $arg2;
800
			}
801
802
			$avatar_type = call_user_func_array($func, $ary);
803
		}
804
		else
805
		{
806
			$avatar_type = call_user_func($func);
807
		}
808
	}
809
810
	switch ($avatar_type)
811
	{
812
		case AVATAR_UPLOAD:
813
			return get_upload_avatar_dim($src, $axis);
814
		break;
815
816
		case AVATAR_GALLERY:
817
			return get_gallery_avatar_dim($src, $axis);
818
		break;
819
820
		case AVATAR_REMOTE:
821
			 // see notes on this functions usage and (hopefully) model $func to avoid this accordingly
822
			return get_remote_avatar_dim($src, $axis);
823
		break;
824
825
		default:
826
			$default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
827
			$default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
828
829
			return $axis ? $default_y : $default_x;
830
		break;
831
	}
832
}
833
834
/**
835
* Obtain the size of the specified uploaded avatar (using the cache if possible) and cache the value
836
*/
837
function get_upload_avatar_dim($source, $axis)
838
{
839
	static $cachedims = false;
840
	static $cachekey = false;
841
842
	if (empty($source))
843
	{
844
		return 0;
845
	}
846
847
	if ($cachekey == $source)
848
	{
849
		return $cachedims[$axis];
850
	}
851
852
	$orig_source = $source;
853
854
	if (substr($source, 0, 7) == 'upload:')
855
	{
856
		$source = substr($source, 7);
857
	}
858
859
	global $convert, $phpbb_root_path, $config, $user;
860
861
	if (!isset($convert->convertor['avatar_path']))
862
	{
863
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'get_upload_avatar_dim()'), __LINE__, __FILE__);
864
	}
865
866
	if (!empty($convert->convertor['avatar_path']) && strpos($source, $convert->convertor['avatar_path']) !== 0)
867
	{
868
		$source = path($convert->convertor['avatar_path'], empty($convert->convertor['source_path_absolute'])) . $source;
869
	}
870
871
	$cachedims = get_image_dim($source);
872
873
	if (empty($cachedims) || empty($cachedims[0]) || empty($cachedims[1]))
874
	{
875
		$default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
876
		$default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
877
878
		$cachedims = array($default_x, $default_y);
879
	}
880
881
	return $cachedims[$axis];
882
}
883
884
/**
885
* Obtain the size of the specified gallery avatar (using the cache if possible) and cache the value
886
*/
887
function get_gallery_avatar_dim($source, $axis)
888
{
889
	if (empty($source))
890
	{
891
		return 0;
892
	}
893
894
	static $avatar_cache = array();
895
896
	if (isset($avatar_cache[$source]))
897
	{
898
		return $avatar_cache[$source][$axis];
899
	}
900
901
	global $convert, $phpbb_root_path, $config, $user;
902
903
	$orig_source = $source;
904
905
	if (!isset($convert->convertor['avatar_gallery_path']))
906
	{
907
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'get_gallery_avatar_dim()'), __LINE__, __FILE__);
908
	}
909
910
	if (!empty($convert->convertor['avatar_gallery_path']) && strpos($source, $convert->convertor['avatar_gallery_path']) !== 0)
911
	{
912
		$source = path($convert->convertor['avatar_gallery_path'], empty($convert->convertor['source_path_absolute'])) . $source;
913
	}
914
915
	$avatar_cache[$orig_source] = get_image_dim($source);
916
917
	if (empty($avatar_cache[$orig_source]) || empty($avatar_cache[$orig_source][0]) || empty($avatar_cache[$orig_source][1]))
918
	{
919
		$default_x = (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
920
		$default_y = (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
921
922
		$avatar_cache[$orig_source] = array($default_x, $default_y);
923
	}
924
925
	return $avatar_cache[$orig_source][$axis];
926
}
927
928
/**
929
* Obtain the size of the specified remote avatar (using the cache if possible) and cache the value
930
* Whilst it's unlikely that remote avatars will be duplicated, it is possible so caching seems the best option
931
* This should only be called from a post processing step due to the possibility of network timeouts
932
*/
933
function get_remote_avatar_dim($src, $axis)
934
{
935
	if (empty($src))
936
	{
937
		return 0;
938
	}
939
940
	static $remote_avatar_cache = array();
941
942
	// an ugly hack: we assume that the dimensions of each remote avatar are accessed exactly twice (x and y)
943
	if (isset($remote_avatar_cache[$src]))
944
	{
945
		$retval = $remote_avatar_cache[$src][$axis];
946
		unset($remote_avatar_cache);
947
		return $retval;
948
	}
949
	
950
	$url_info = @parse_url($src);
951
	if (empty($url_info['host']))
952
	{
953
		return 0;
954
	}
955
	$host = $url_info['host'];
956
	$port = (isset($url_info['port'])) ? $url_info['port'] : 0;
957
	$protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : 'http';
958
	if (empty($port))
959
	{
960
		switch(strtolower($protocol))
961
		{
962
			case 'ftp':
963
				$port = 21;
964
				break;
965
				
966
			case 'https':
967
				$port = 443;
968
				break;
969
			
970
			default:
971
				$port = 80;
972
		}
973
	}
974
	
975
	$timeout = @ini_get('default_socket_timeout');
976
	@ini_set('default_socket_timeout', 2);
977
	
978
	// We're just trying to reach the server to avoid timeouts
979
	$fp = @fsockopen($host, $port, $errno, $errstr, 1);
980
	if ($fp)
981
	{
982
		$remote_avatar_cache[$src] = @getimagesize($src);
983
		fclose($fp);
984
	}
985
	
986
	$default_x 	= (defined('DEFAULT_AVATAR_X_CUSTOM')) ? DEFAULT_AVATAR_X_CUSTOM : DEFAULT_AVATAR_X;
987
	$default_y 	= (defined('DEFAULT_AVATAR_Y_CUSTOM')) ? DEFAULT_AVATAR_Y_CUSTOM : DEFAULT_AVATAR_Y;
988
	$default 	= array($default_x, $default_y);
989
	
990
	if (empty($remote_avatar_cache[$src]) || empty($remote_avatar_cache[$src][0]) || empty($remote_avatar_cache[$src][1]))
991
	{
992
		$remote_avatar_cache[$src] = $default;
993
	}
994
	else
995
	{
996
		// We trust gallery and uploaded avatars to conform to the size settings; we might have to adjust here
997
		if ($remote_avatar_cache[$src][0] > $default_x || $remote_avatar_cache[$src][1] > $default_y)
998
		{
999
			$bigger = ($remote_avatar_cache[$src][0] > $remote_avatar_cache[$src][1]) ? 0 : 1;
1000
			$ratio = $default[$bigger] / $remote_avatar_cache[$src][$bigger];
1001
			$remote_avatar_cache[$src][0] = (int)($remote_avatar_cache[$src][0] * $ratio);
1002
			$remote_avatar_cache[$src][1] = (int)($remote_avatar_cache[$src][1] * $ratio);
1003
		}
1004
	}
1005
	
1006
	@ini_set('default_socket_timeout', $timeout);
1007
	return $remote_avatar_cache[$src][$axis];
1008
}
1009
1010
function set_user_options()
1011
{
1012
	global $convert_row;
1013
1014
	// Key need to be set in row, else default value is chosen
1015
	$keyoptions = array(
1016
		'viewimg'		=> array('bit' => 0, 'default' => 1),
1017
		'viewflash'		=> array('bit' => 1, 'default' => 1),
1018
		'viewsmilies'	=> array('bit' => 2, 'default' => 1),
1019
		'viewsigs'		=> array('bit' => 3, 'default' => 1),
1020
		'viewavatars'	=> array('bit' => 4, 'default' => 1),
1021
		'viewcensors'	=> array('bit' => 5, 'default' => 1),
1022
		'attachsig'		=> array('bit' => 6, 'default' => 0),
1023
		'bbcode'		=> array('bit' => 8, 'default' => 1),
1024
		'smilies'		=> array('bit' => 9, 'default' => 1),
1025
		'popuppm'		=> array('bit' => 10, 'default' => 0),
1026
	);
1027
1028
	$option_field = 0;
1029
1030
	foreach ($keyoptions as $key => $key_ary)
1031
	{
1032
		$value = (isset($convert_row[$key])) ? (int) $convert_row[$key] : $key_ary['default'];
1033
1034
		if ($value && !($option_field & 1 << $key_ary['bit']))
1035
		{
1036
			$option_field += 1 << $key_ary['bit'];
1037
		}
1038
	}
1039
1040
	return $option_field;
1041
}
1042
1043
/**
1044
* Index messages on the fly as we convert them
1045
* @todo naderman, can you check that this works with the new search plugins as it's use is currently disabled (and thus untested)
1046
function search_indexing($message = '')
1047
{
1048
	global $fulltext_search, $convert_row;
1049
1050
	if (!isset($convert_row['post_id']))
1051
	{
1052
		return;
1053
	}
1054
1055
	if (!$message)
1056
	{
1057
		if (!isset($convert_row['message']))
1058
		{
1059
			return;
1060
		}
1061
1062
		$message = $convert_row['message'];
1063
	}
1064
1065
	$title = (isset($convert_row['title'])) ? $convert_row['title'] : '';
1066
1067
	$fulltext_search->index('post', $convert_row['post_id'], $message, $title, $convert_row['poster_id'], $convert_row['forum_id']);
1068
}
1069
*/
1070
1071
function make_unique_filename($filename)
1072
{
1073
	if (!strlen($filename))
1074
	{
1075
		$filename = md5(unique_id()) . '.dat';
1076
	}
1077
	else if ($filename[0] == '.')
1078
	{
1079
		$filename = md5(unique_id()) . $filename;
1080
	}
1081
	else if (preg_match('/\.([a-z]+)$/i', $filename, $m))
1082
	{
1083
		$filename = preg_replace('/\.([a-z]+)$/i', '_' . md5(unique_id()) . '.\1', $filename);
1084
	}
1085
	else
1086
	{
1087
		$filename .= '_' . md5(unique_id()) . '.dat';
1088
	}
1089
1090
	return $filename;
1091
}
1092
1093
function words_unique(&$words)
1094
{
1095
	reset($words);
1096
	$return_array = array();
1097
1098
	$word = current($words);
1099
	do
1100
	{
1101
		$return_array[$word] = $word;
1102
	}
1103
	while ($word = next($words));
1104
1105
	return $return_array;
1106
}
1107
1108
/**
1109
* Adds a user to the specified group and optionally makes them a group leader
1110
* This function does not create the group if it does not exist and so should only be called after the groups have been created
1111
*/
1112
function add_user_group($group_id, $user_id, $group_leader=false)
1113
{
1114
	global $convert, $phpbb_root_path, $config, $user, $db;
1115
	
1116
	$sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1117
		'group_id'		=> $group_id,
1118
		'user_id'		=> $user_id,
1119
		'group_leader'	=> ($group_leader) ? 1 : 0,
1120
		'user_pending'	=> 0));
1121
	$db->sql_query($sql);
1122
}
1123
1124
// STANDALONE FUNCTIONS
1125
1126
/**
1127
* Add users to the pre-defined "special" groups
1128
*
1129
* @param string $group The name of the special group to add to
1130
* @param string $select_query An SQL query to retrieve the user(s) to add to the group
1131
*/
1132
function user_group_auth($group, $select_query, $use_src_db)
1133
{
1134
	global $convert, $phpbb_root_path, $config, $user, $db, $src_db, $same_db;
1135
1136
	if (!in_array($group, array('guests', 'registered', 'registered_coppa', 'global_moderators', 'administrators', 'bots')))
1137
	{
1138
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_WRONG_GROUP'], $group, 'user_group_auth()'), __LINE__, __FILE__, true);
1139
		return;
1140
	}
1141
1142
	$sql = 'SELECT group_id
1143
		FROM ' . GROUPS_TABLE . "
1144
		WHERE group_name = '" . $db->sql_escape(strtoupper($group)) . "'";
1145
	$result = $db->sql_query($sql);
1146
	$group_id = (int) $db->sql_fetchfield('group_id');
1147
	$db->sql_freeresult($result);
1148
1149
	if (!$group_id)
1150
	{
1151
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GROUP'], $group, 'user_group_auth()'), __LINE__, __FILE__, true);
1152
		return;
1153
	}
1154
1155
	if ($same_db || !$use_src_db)
1156
	{
1157
		$sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' (user_id, group_id, user_pending)
1158
			' . str_replace('{' . strtoupper($group) . '}', $group_id . ', 0', $select_query);
1159
		$db->sql_query($sql);
1160
	}
1161
	else
1162
	{
1163
		$result = $src_db->sql_query(str_replace('{' . strtoupper($group) . '}', $group_id . ' ', $select_query));
1164
		while ($row = $src_db->sql_fetchrow($result))
1165
		{
1166
			// this might become quite a lot of INSERTS unfortunately
1167
			$sql = 'INSERT INTO ' . USER_GROUP_TABLE . " (user_id, group_id, user_pending)
1168
				VALUES ({$row['user_id']}, $group_id, 0)";
1169
			$db->sql_query($sql);
1170
		}
1171
		$src_db->sql_freeresult($result);
1172
	}
1173
}
1174
1175
/**
1176
* Retrieves configuration information from the source forum and caches it as an array
1177
* Both database and file driven configuration formats can be handled
1178
* (the type used is specified in $config_schema, see convert_phpbb20.php for more details)
1179
*/
1180
function get_config()
1181
{
1182
	static $convert_config;
1183
	global $user;
1184
1185
	if (isset($convert_config))
1186
	{
1187
		return $convert_config;
1188
	}
1189
1190
	global $src_db, $same_db, $phpbb_root_path, $config;
1191
	global $convert;
1192
1193
	if ($convert->config_schema['table_format'] != 'file')
1194
	{
1195
		if ($convert->mysql_convert && $same_db)
1196
		{
1197
			$src_db->sql_query("SET NAMES 'binary'");
1198
		}
1199
1200
		$sql = 'SELECT * FROM ' . $convert->src_table_prefix . $convert->config_schema['table_name'];
1201
		$result = $src_db->sql_query($sql);
1202
		$row = $src_db->sql_fetchrow($result);
1203
1204
		if (!$row)
1205
		{
1206
			$convert->p_master->error($user->lang['CONV_ERROR_GET_CONFIG'], __LINE__, __FILE__);
1207
		}
1208
	}
1209
1210
	if (is_array($convert->config_schema['table_format']))
1211
	{
1212
		$convert_config = array();
1213
		list($key, $val) = each($convert->config_schema['table_format']);
1214
1215
		do
1216
		{
1217
			$convert_config[$row[$key]] = $row[$val];
1218
		}
1219
		while ($row = $src_db->sql_fetchrow($result));
1220
		$src_db->sql_freeresult($result);
1221
1222
		if ($convert->mysql_convert && $same_db)
1223
		{
1224
			$src_db->sql_query("SET NAMES 'utf8'");
1225
		}
1226
	}
1227
	else if ($convert->config_schema['table_format'] == 'file')
1228
	{
1229
		$filename = $convert->options['forum_path'] . '/' . $convert->config_schema['filename'];
1230
		if (!file_exists($filename))
1231
		{
1232
			$convert->p_master->error($user->lang['FILE_NOT_FOUND'] . ': ' . $filename, __LINE__, __FILE__);
1233
		}
1234
1235
		$convert_config = extract_variables_from_file($filename);
1236
		if (!empty($convert->config_schema['array_name']))
1237
		{
1238
			$convert_config = $convert_config[$convert->config_schema['array_name']];
1239
		}
1240
	}
1241
	else
1242
	{
1243
		$convert_config = $row;
1244
		if ($convert->mysql_convert && $same_db)
1245
		{
1246
			$src_db->sql_query("SET NAMES 'utf8'");
1247
		}
1248
	}
1249
1250
	if (!sizeof($convert_config))
1251
	{
1252
		$convert->p_master->error($user->lang['CONV_ERROR_CONFIG_EMPTY'], __LINE__, __FILE__);
1253
	}
1254
1255
	return $convert_config;
1256
}
1257
1258
/**
1259
* Transfers the relevant configuration information from the source forum
1260
* The mapping of fields is specified in $config_schema, see convert_phpbb20.php for more details
1261
*/
1262
function restore_config($schema)
1263
{
1264
	global $db, $config;
1265
1266
	$convert_config = get_config();
1267
	foreach ($schema['settings'] as $config_name => $src)
1268
	{
1269
		if (preg_match('/(.*)\((.*)\)/', $src, $m))
1270
		{
1271
			$var = (empty($m[2]) || empty($convert_config[$m[2]])) ? "''" : "'" . addslashes($convert_config[$m[2]]) . "'";
1272
			$exec = '$config_value = ' . $m[1] . '(' . $var . ');';
1273
			eval($exec);
1274
		}
1275
		else
1276
		{
1277
			$config_value = (isset($convert_config[$src])) ? $convert_config[$src] : '';
1278
		}
1279
1280
		if ($config_value !== '')
1281
		{
1282
			// Most are...
1283
			if (is_string($config_value))
1284
			{
1285
				$config_value = utf8_htmlspecialchars($config_value);
1286
			}
1287
1288
			set_config($config_name, $config_value);
1289
		}
1290
	}
1291
}
1292
1293
/**
1294
* Update the count of PM's in custom folders for all users
1295
*/
1296
function update_folder_pm_count()
1297
{
1298
	global $db, $convert, $user;
1299
1300
	$sql = 'SELECT user_id, folder_id, COUNT(msg_id) as num_messages
1301
		FROM ' . PRIVMSGS_TO_TABLE . '
1302
		WHERE folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ', ' . PRIVMSGS_INBOX . ', ' . PRIVMSGS_OUTBOX . ', ' . PRIVMSGS_SENTBOX . ')
1303
		GROUP BY folder_id, user_id';
1304
	$result = $db->sql_query($sql);
1305
1306
	while ($row = $db->sql_fetchrow($result))
1307
	{
1308
		$db->sql_query('UPDATE ' . PRIVMSGS_FOLDER_TABLE . ' SET pm_count = ' . $row['num_messages'] . '
1309
			WHERE user_id = ' . $row['user_id'] . ' AND folder_id = ' . $row['folder_id']);
1310
	}
1311
	$db->sql_freeresult($result);
1312
}
1313
1314
// Functions mainly used by the main convertor script
1315
1316
function path($path, $path_relative = true)
1317
{
1318
	if ($path === false)
1319
	{
1320
		return '';
1321
	}
1322
1323
	if (substr($path, -1) != '/')
1324
	{
1325
		$path .= '/';
1326
	}
1327
1328
	if (!$path_relative)
1329
	{
1330
		return $path;
1331
	}
1332
1333
	if (substr($path, 0, 1) == '/')
1334
	{
1335
		$path = substr($path, 1);
1336
	}
1337
1338
	return $path;
1339
}
1340
1341
/**
1342
* Extract the variables defined in a configuration file
1343
* @todo As noted by Xore we need to look at this from a security perspective
1344
*/
1345
function extract_variables_from_file($_filename)
1346
{
1347
	include($_filename);
1348
1349
	$vars = get_defined_vars();
1350
	unset($vars['_filename']);
1351
1352
	return $vars;
1353
}
1354
1355
function get_path($src_path, $src_url, $test_file)
1356
{
1357
	global $config, $phpbb_root_path, $phpEx;
1358
1359
	$board_config = get_config();
1360
1361
	$test_file = preg_replace('/\.php$/i', ".$phpEx", $test_file);
1362
	$src_path = path($src_path);
1363
1364
	if (@file_exists($phpbb_root_path . $src_path . $test_file))
1365
	{
1366
		return $src_path;
1367
	}
1368
1369
	if (!empty($src_url) && !empty($board_config['server_name']))
1370
	{
1371
		if (!preg_match('#https?://([^/]+)(.*)#i', $src_url, $m))
1372
		{
1373
			return false;
1374
		}
1375
1376
		if ($m[1] != $board_config['server_name'])
1377
		{
1378
			return false;
1379
		}
1380
1381
		$url_parts = explode('/', $m[2]);
1382
		if (substr($src_url, -1) != '/')
1383
		{
1384
			if (preg_match('/.*\.([a-z0-9]{3,4})$/i', $url_parts[sizeof($url_parts) - 1]))
1385
			{
1386
				$url_parts[sizeof($url_parts) - 1] = '';
1387
			}
1388
			else
1389
			{
1390
				$url_parts[] = '';
1391
			}
1392
		}
1393
1394
		$script_path = $board_config['script_path'];
1395
		if (substr($script_path, -1) == '/')
1396
		{
1397
			$script_path = substr($script_path, 0, -1);
1398
		}
1399
1400
		$path_array = array();
1401
1402
		$phpbb_parts = explode('/', $script_path);
1403
		for ($i = 0; $i < sizeof($url_parts); ++$i)
1404
		{
1405
			if ($i < sizeof($phpbb_parts[$i]) && $url_parts[$i] == $phpbb_parts[$i])
1406
			{
1407
				$path_array[] = $url_parts[$i];
1408
				unset($url_parts[$i]);
1409
			}
1410
			else
1411
			{
1412
				$path = '';
1413
				for ($j = $i; $j < sizeof($phpbb_parts); ++$j)
1414
				{
1415
					$path .= '../';
1416
				}
1417
				$path .= implode('/', $url_parts);
1418
				break;
1419
			}
1420
		}
1421
1422
		if (!empty($path))
1423
		{
1424
			if (@file_exists($phpbb_root_path . $path . $test_file))
1425
			{
1426
				return $path;
1427
			}
1428
		}
1429
	}
1430
1431
	return false;
1432
}
1433
1434
function compare_table($tables, $tablename, &$prefixes)
1435
{
1436
	for ($i = 0, $table_size = sizeof($tables); $i < $table_size; ++$i)
1437
	{
1438
		if (preg_match('/(.*)' . $tables[$i] . '$/', $tablename, $m))
1439
		{
1440
			if (empty($m[1]))
1441
			{
1442
				$m[1] = '*';
1443
			}
1444
1445
			if (isset($prefixes[$m[1]]))
1446
			{
1447
				$prefixes[$m[1]]++;
1448
			}
1449
			else
1450
			{
1451
				$prefixes[$m[1]] = 1;
1452
			}
1453
		}
1454
	}
1455
}
1456
1457
/**
1458
* Grant permissions to a specified user or group
1459
*
1460
* @param string $ug_type user|group|user_role|group_role
1461
* @param mixed $forum_id forum ids (array|int|0) -> 0 == all forums
1462
* @param mixed $ug_id [int] user_id|group_id : [string] usergroup name
1463
* @param mixed $acl_list [string] acl entry : [array] acl entries : [string] role entry
1464
* @param int $setting ACL_YES|ACL_NO|ACL_NEVER
1465
*/
1466
function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
1467
{
1468
	global $db, $convert, $user, $config;
1469
	static $acl_option_ids, $group_ids;
1470
1471
	if (($ug_type == 'group' || $ug_type == 'group_role') && is_string($ug_id))
1472
	{
1473
		if (!isset($group_ids[$ug_id]))
1474
		{
1475
			$sql = 'SELECT group_id
1476
				FROM ' . GROUPS_TABLE . "
1477
				WHERE group_name = '" . $db->sql_escape(strtoupper($ug_id)) . "'";
1478
			$result = $db->sql_query_limit($sql, 1);
1479
			$id = (int) $db->sql_fetchfield('group_id');
1480
			$db->sql_freeresult($result);
1481
1482
			if (!$id)
1483
			{
1484
				return;
1485
			}
1486
1487
			$group_ids[$ug_id] = $id;
1488
		}
1489
1490
		$ug_id = (int) $group_ids[$ug_id];
1491
	}
1492
1493
	$table = ($ug_type == 'user' || $ug_type == 'user_role') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
1494
	$id_field = ($ug_type == 'user' || $ug_type == 'user_role') ? 'user_id' : 'group_id';
1495
1496
	// Role based permissions are the simplest to handle so check for them first
1497
	if ($ug_type == 'user_role' || $ug_type == 'group_role')
1498
	{
1499
		if (is_numeric($forum_id))
1500
		{
1501
			$sql = 'SELECT role_id
1502
				FROM ' . ACL_ROLES_TABLE . "
1503
				WHERE role_name = 'ROLE_" . $db->sql_escape($acl_list) . "'";
1504
			$result = $db->sql_query_limit($sql, 1);
1505
			$row = $db->sql_fetchrow($result);
1506
			$db->sql_freeresult($result);
1507
1508
			// If we have no role id there is something wrong here
1509
			if ($row)
1510
			{
1511
				$sql = "INSERT INTO $table ($id_field, forum_id, auth_role_id) VALUES ($ug_id, $forum_id, " . $row['role_id'] . ')';
1512
				$db->sql_query($sql);
1513
			}
1514
		}
1515
1516
		return;
1517
	}
1518
1519
	// Build correct parameters
1520
	$auth = array();
1521
1522
	if (!is_array($acl_list))
1523
	{
1524
		$auth = array($acl_list => $setting);
1525
	}
1526
	else
1527
	{
1528
		foreach ($acl_list as $auth_option)
1529
		{
1530
			$auth[$auth_option] = $setting;
1531
		}
1532
	}
1533
	unset($acl_list);
1534
1535
	if (!is_array($forum_id))
1536
	{
1537
		$forum_id = array($forum_id);
1538
	}
1539
1540
	// Set any flags as required
1541
	foreach ($auth as $auth_option => $acl_setting)
1542
	{
1543
		$flag = substr($auth_option, 0, strpos($auth_option, '_') + 1);
1544
		if (empty($auth[$flag]))
1545
		{
1546
			$auth[$flag] = $acl_setting;
1547
		}
1548
	}
1549
1550
	if (!is_array($acl_option_ids) || empty($acl_option_ids))
1551
	{
1552
		$sql = 'SELECT auth_option_id, auth_option
1553
			FROM ' . ACL_OPTIONS_TABLE;
1554
		$result = $db->sql_query($sql);
1555
1556
		while ($row = $db->sql_fetchrow($result))
1557
		{
1558
			$acl_option_ids[$row['auth_option']] = $row['auth_option_id'];
1559
		}
1560
		$db->sql_freeresult($result);
1561
	}
1562
1563
	$sql_forum = 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id), false, true);
1564
1565
	$sql = ($ug_type == 'user') ? 'SELECT o.auth_option_id, o.auth_option, a.forum_id, a.auth_setting FROM ' . ACL_USERS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . " o WHERE a.auth_option_id = o.auth_option_id $sql_forum AND a.user_id = $ug_id" : 'SELECT o.auth_option_id, o.auth_option, a.forum_id, a.auth_setting FROM ' . ACL_GROUPS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . " o WHERE a.auth_option_id = o.auth_option_id $sql_forum AND a.group_id = $ug_id";
1566
	$result = $db->sql_query($sql);
1567
1568
	$cur_auth = array();
1569
	while ($row = $db->sql_fetchrow($result))
1570
	{
1571
		$cur_auth[$row['forum_id']][$row['auth_option_id']] = $row['auth_setting'];
1572
	}
1573
	$db->sql_freeresult($result);
1574
1575
	$sql_ary = array();
1576
	foreach ($forum_id as $forum)
1577
	{
1578
		foreach ($auth as $auth_option => $setting)
1579
		{
1580
			$auth_option_id = $acl_option_ids[$auth_option];
1581
1582
			if (!$auth_option_id)
1583
			{
1584
				continue;
1585
			}
1586
1587
			switch ($setting)
1588
			{
1589
				case ACL_NO:
1590
					if (isset($cur_auth[$forum][$auth_option_id]))
1591
					{
1592
						$sql_ary['delete'][] = "DELETE FROM $table
1593
							WHERE forum_id = $forum
1594
								AND auth_option_id = $auth_option_id
1595
								AND $id_field = $ug_id";
1596
					}
1597
				break;
1598
1599
				default:
1600
					if (!isset($cur_auth[$forum][$auth_option_id]))
1601
					{
1602
						$sql_ary['insert'][] = "$ug_id, $forum, $auth_option_id, $setting";
1603
					}
1604
					else if ($cur_auth[$forum][$auth_option_id] != $setting)
1605
					{
1606
						$sql_ary['update'][] = "UPDATE " . $table . "
1607
							SET auth_setting = $setting
1608
							WHERE $id_field = $ug_id
1609
								AND forum_id = $forum
1610
								AND auth_option_id = $auth_option_id";
1611
					}
1612
			}
1613
		}
1614
	}
1615
	unset($cur_auth);
1616
1617
	$sql = '';
1618
	foreach ($sql_ary as $sql_type => $sql_subary)
1619
	{
1620
		switch ($sql_type)
1621
		{
1622
			case 'insert':
1623
				switch ($db->sql_layer)
1624
				{
1625
					case 'mysql':
1626
					case 'mysql4':
1627
						$sql = 'VALUES ' . implode(', ', preg_replace('#^(.*?)$#', '(\1)', $sql_subary));
1628
					break;
1629
1630
					case 'mssql':
1631
					case 'sqlite':
1632
						$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
1633
					break;
1634
1635
					default:
1636
						foreach ($sql_subary as $sql)
1637
						{
1638
							$sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) VALUES ($sql)";
1639
							$db->sql_query($sql);
1640
							$sql = '';
1641
						}
1642
				}
1643
1644
				if ($sql != '')
1645
				{
1646
					$sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) $sql";
1647
					$db->sql_query($sql);
1648
				}
1649
			break;
1650
1651
			case 'update':
1652
			case 'delete':
1653
				foreach ($sql_subary as $sql)
1654
				{
1655
					$db->sql_query($sql);
1656
					$sql = '';
1657
				}
1658
			break;
1659
		}
1660
		unset($sql_ary[$sql_type]);
1661
	}
1662
	unset($sql_ary);
1663
1664
}
1665
1666
/**
1667
* Update the count of unread private messages for all users
1668
*/
1669
function update_unread_count()
1670
{
1671
	global $db;
1672
1673
	$sql = 'SELECT user_id, COUNT(msg_id) as num_messages
1674
		FROM ' . PRIVMSGS_TO_TABLE . '
1675
		WHERE pm_unread = 1
1676
			AND folder_id <> ' . PRIVMSGS_OUTBOX . '
1677
		GROUP BY user_id';
1678
	$result = $db->sql_query($sql);
1679
1680
	while ($row = $db->sql_fetchrow($result))
1681
	{
1682
		$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_unread_privmsg = ' . $row['num_messages'] . '
1683
			WHERE user_id = ' . $row['user_id']);
1684
	}
1685
	$db->sql_freeresult($result);
1686
}
1687
1688
/**
1689
* Add any of the pre-defined "special" groups which are missing from the database
1690
*/
1691
function add_default_groups()
1692
{
1693
	global $db;
1694
1695
	$default_groups = array(
1696
		'GUESTS'			=> array('', 0, 0),
1697
		'REGISTERED'		=> array('', 0, 0),
1698
		'REGISTERED_COPPA'	=> array('', 0, 0),
1699
		'GLOBAL_MODERATORS'	=> array('00AA00', 1, 0),
1700
		'ADMINISTRATORS'	=> array('AA0000', 1, 1),
1701
		'BOTS'				=> array('9E8DA7', 0, 0)
1702
	);
1703
1704
	$sql = 'SELECT *
1705
		FROM ' . GROUPS_TABLE . '
1706
		WHERE ' . $db->sql_in_set('group_name', array_keys($default_groups));
1707
	$result = $db->sql_query($sql);
1708
1709
	while ($row = $db->sql_fetchrow($result))
1710
	{
1711
		unset($default_groups[strtoupper($row['group_name'])]);
1712
	}
1713
	$db->sql_freeresult($result);
1714
1715
	$sql_ary = array();
1716
1717
	foreach ($default_groups as $name => $data)
1718
	{
1719
		$sql_ary[] = array(
1720
			'group_name'			=> (string) $name,
1721
			'group_desc'			=> '',
1722
			'group_desc_uid'		=> '',
1723
			'group_desc_bitfield'	=> '',
1724
			'group_type'			=> GROUP_SPECIAL,
1725
			'group_colour'			=> (string) $data[0],
1726
			'group_legend'			=> (int) $data[1],
1727
			'group_founder_manage'	=> (int) $data[2]
1728
		);
1729
	}
1730
1731
	if (sizeof($sql_ary))
1732
	{
1733
		$db->sql_multi_insert(GROUPS_TABLE, $sql_ary);
1734
	}
1735
}
1736
1737
1738
/**
1739
* Sync post count. We might need to do this in batches.
1740
*/
1741
function sync_post_count($offset, $limit)
1742
{
1743
	global $db;
1744
	$sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
1745
			FROM ' . POSTS_TABLE . '
1746
			WHERE post_postcount = 1
1747
			GROUP BY poster_id
1748
			ORDER BY poster_id';
1749
	$result = $db->sql_query_limit($sql, $limit, $offset);
1750
1751
	while ($row = $db->sql_fetchrow($result))
1752
	{
1753
		$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['poster_id']}");
1754
	}
1755
	$db->sql_freeresult($result);
1756
}
1757
1758
/**
1759
* Add the search bots into the database
1760
* This code should be used in execute_last if the source database did not have bots
1761
* If you are converting bots this function should not be called
1762
* @todo We might want to look at sharing the bot list between the install code and this code for consistancy
1763
*/
1764
function add_bots()
1765
{
1766
	global $db, $convert, $user, $config, $phpbb_root_path, $phpEx;
1767
1768
	$db->sql_query($convert->truncate_statement . BOTS_TABLE);
1769
1770
	$sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'";
1771
	$result = $db->sql_query($sql);
1772
	$group_id = (int) $db->sql_fetchfield('group_id', false, $result);
1773
	$db->sql_freeresult($result);
1774
1775
	if (!$group_id)
1776
	{
1777
		add_default_groups();
1778
1779
		$sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'";
1780
		$result = $db->sql_query($sql);
1781
		$group_id = (int) $db->sql_fetchfield('group_id', false, $result);
1782
		$db->sql_freeresult($result);
1783
1784
		if (!$group_id)
1785
		{
1786
			global $install;
1787
			$install->error($user->lang['CONV_ERROR_INCONSISTENT_GROUPS'], __LINE__, __FILE__);
1788
		}
1789
	}
1790
1791
	$bots = array(
1792
		'AdsBot [Google]'			=> array('AdsBot-Google', ''),
1793
		'Alexa [Bot]'				=> array('ia_archiver', ''),
1794
		'Alta Vista [Bot]'			=> array('Scooter/', ''),
1795
		'Ask Jeeves [Bot]'			=> array('Ask Jeeves', ''),
1796
		'Baidu [Spider]'			=> array('Baiduspider+(', ''),
1797
		'Exabot [Bot]'				=> array('Exabot/', ''),
1798
		'FAST Enterprise [Crawler]'	=> array('FAST Enterprise Crawler', ''),
1799
		'FAST WebCrawler [Crawler]'	=> array('FAST-WebCrawler/', ''),
1800
		'Francis [Bot]'				=> array('http://www.neomo.de/', ''),
1801
		'Gigabot [Bot]'				=> array('Gigabot/', ''),
1802
		'Google Adsense [Bot]'		=> array('Mediapartners-Google', ''),
1803
		'Google Desktop'			=> array('Google Desktop', ''),
1804
		'Google Feedfetcher'		=> array('Feedfetcher-Google', ''),
1805
		'Google [Bot]'				=> array('Googlebot', ''),
1806
		'Heise IT-Markt [Crawler]'	=> array('heise-IT-Markt-Crawler', ''),
1807
		'Heritrix [Crawler]'		=> array('heritrix/1.', ''),
1808
		'IBM Research [Bot]'		=> array('ibm.com/cs/crawler', ''),
1809
		'ICCrawler - ICjobs'		=> array('ICCrawler - ICjobs', ''),
1810
		'ichiro [Crawler]'			=> array('ichiro/2', ''),
1811
		'Majestic-12 [Bot]'			=> array('MJ12bot/', ''),
1812
		'Metager [Bot]'				=> array('MetagerBot/', ''),
1813
		'MSN NewsBlogs'				=> array('msnbot-NewsBlogs/', ''),
1814
		'MSN [Bot]'					=> array('msnbot/', ''),
1815
		'MSNbot Media'				=> array('msnbot-media/', ''),
1816
		'NG-Search [Bot]'			=> array('NG-Search/', ''),
1817
		'Nutch [Bot]'				=> array('http://lucene.apache.org/nutch/', ''),
1818
		'Nutch/CVS [Bot]'			=> array('NutchCVS/', ''),
1819
		'OmniExplorer [Bot]'		=> array('OmniExplorer_Bot/', ''),
1820
		'Online link [Validator]'	=> array('online link validator', ''),
1821
		'psbot [Picsearch]'			=> array('psbot/0', ''),
1822
		'Seekport [Bot]'			=> array('Seekbot/', ''),
1823
		'Sensis [Crawler]'			=> array('Sensis Web Crawler', ''),
1824
		'SEO Crawler'				=> array('SEO search Crawler/', ''),
1825
		'Seoma [Crawler]'			=> array('Seoma [SEO Crawler]', ''),
1826
		'SEOSearch [Crawler]'		=> array('SEOsearch/', ''),
1827
		'Snappy [Bot]'				=> array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
1828
		'Steeler [Crawler]'			=> array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
1829
		'Synoo [Bot]'				=> array('SynooBot/', ''),
1830
		'Telekom [Bot]'				=> array('crawleradmin.t-info@telekom.de', ''),
1831
		'TurnitinBot [Bot]'			=> array('TurnitinBot/', ''),
1832
		'Voyager [Bot]'				=> array('voyager/1.0', ''),
1833
		'W3 [Sitesearch]'			=> array('W3 SiteSearch Crawler', ''),
1834
		'W3C [Linkcheck]'			=> array('W3C-checklink/', ''),
1835
		'W3C [Validator]'			=> array('W3C_*Validator', ''),
1836
		'WiseNut [Bot]'				=> array('http://www.WISEnutbot.com', ''),
1837
		'YaCy [Bot]'				=> array('yacybot', ''),
1838
		'Yahoo MMCrawler [Bot]'		=> array('Yahoo-MMCrawler/', ''),
1839
		'Yahoo Slurp [Bot]'			=> array('Yahoo! DE Slurp', ''),
1840
		'Yahoo [Bot]'				=> array('Yahoo! Slurp', ''),
1841
		'YahooSeeker [Bot]'			=> array('YahooSeeker/', ''),
1842
	);
1843
1844
	if (!function_exists('user_add'))
1845
	{
1846
		include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1847
	}
1848
1849
	foreach ($bots as $bot_name => $bot_ary)
1850
	{
1851
		$user_row = array(
1852
			'user_type'				=> USER_IGNORE,
1853
			'group_id'				=> $group_id,
1854
			'username'				=> $bot_name,
1855
			'user_regdate'			=> time(),
1856
			'user_password'			=> '',
1857
			'user_colour'			=> '9E8DA7',
1858
			'user_email'			=> '',
1859
			'user_lang'				=> $config['default_lang'],
1860
			'user_style'			=> 1,
1861
			'user_timezone'			=> 0,
1862
			'user_allow_massemail'	=> 0,
1863
		);
1864
1865
		$user_id = user_add($user_row);
1866
1867
		if ($user_id)
1868
		{
1869
			$sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1870
				'bot_active'	=> 1,
1871
				'bot_name'		=> $bot_name,
1872
				'user_id'		=> $user_id,
1873
				'bot_agent'		=> $bot_ary[0],
1874
				'bot_ip'		=> $bot_ary[1])
1875
			);
1876
			$db->sql_query($sql);
1877
		}
1878
	}
1879
}
1880
1881
/**
1882
* Update any dynamic configuration variables after the conversion is finished
1883
* @todo Confirm that this updates all relevant values since it has not necessarily been kept in sync with all changes
1884
*/
1885
function update_dynamic_config()
1886
{
1887
	global $db, $config;
1888
1889
	// Get latest username
1890
	$sql = 'SELECT user_id, username, user_colour
1891
		FROM ' . USERS_TABLE . '
1892
		WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
1893
1894
	if (!empty($config['increment_user_id']))
1895
	{
1896
		$sql .= ' AND user_id <> ' . $config['increment_user_id'];
1897
	}
1898
1899
	$sql .= ' ORDER BY user_id DESC';
1900
1901
	$result = $db->sql_query_limit($sql, 1);
1902
	$row = $db->sql_fetchrow($result);
1903
	$db->sql_freeresult($result);
1904
1905
	if ($row)
1906
	{
1907
		set_config('newest_user_id', $row['user_id'], true);
1908
		set_config('newest_username', $row['username'], true);
1909
		set_config('newest_user_colour', $row['user_colour'], true);
1910
	}
1911
1912
//	Also do not reset record online user/date. There will be old data or the fresh data from the schema.
1913
//	set_config('record_online_users', 1, true);
1914
//	set_config('record_online_date', time(), true);
1915
1916
	$sql = 'SELECT COUNT(post_id) AS stat
1917
		FROM ' . POSTS_TABLE . '
1918
		WHERE post_approved = 1';
1919
	$result = $db->sql_query($sql);
1920
	$row = $db->sql_fetchrow($result);
1921
	$db->sql_freeresult($result);
1922
1923
	set_config('num_posts', (int) $row['stat'], true);
1924
1925
	$sql = 'SELECT COUNT(topic_id) AS stat
1926
		FROM ' . TOPICS_TABLE . '
1927
		WHERE topic_approved = 1';
1928
	$result = $db->sql_query($sql);
1929
	$row = $db->sql_fetchrow($result);
1930
	$db->sql_freeresult($result);
1931
1932
	set_config('num_topics', (int) $row['stat'], true);
1933
1934
	$sql = 'SELECT COUNT(user_id) AS stat
1935
		FROM ' . USERS_TABLE . '
1936
		WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')';
1937
	$result = $db->sql_query($sql);
1938
	$row = $db->sql_fetchrow($result);
1939
	$db->sql_freeresult($result);
1940
1941
	set_config('num_users', (int) $row['stat'], true);
1942
1943
	$sql = 'SELECT COUNT(attach_id) as stat
1944
		FROM ' . ATTACHMENTS_TABLE . '
1945
		WHERE is_orphan = 0';
1946
	$result = $db->sql_query($sql);
1947
	set_config('num_files', (int) $db->sql_fetchfield('stat'), true);
1948
	$db->sql_freeresult($result);
1949
1950
	$sql = 'SELECT SUM(filesize) as stat
1951
		FROM ' . ATTACHMENTS_TABLE . '
1952
		WHERE is_orphan = 0';
1953
	$result = $db->sql_query($sql);
1954
	set_config('upload_dir_size', (int) $db->sql_fetchfield('stat'), true);
1955
	$db->sql_freeresult($result);
1956
1957
	/**
1958
	* We do not resync users post counts - this can be done by the admin after conversion if wanted.
1959
	$sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
1960
		FROM ' . POSTS_TABLE . '
1961
		WHERE post_postcount = 1
1962
		GROUP BY poster_id';
1963
	$result = $db->sql_query($sql);
1964
1965
	while ($row = $db->sql_fetchrow($result))
1966
	{
1967
		$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['poster_id']}");
1968
	}
1969
	$db->sql_freeresult($result);
1970
	*/
1971
}
1972
1973
/**
1974
* Updates topics_posted entries
1975
*/
1976
function update_topics_posted()
1977
{
1978
	global $db, $config;
1979
1980
	switch ($db->sql_layer)
1981
	{
1982
		case 'sqlite':
1983
		case 'firebird':
1984
			$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
1985
		break;
1986
1987
		default:
1988
			$db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
1989
		break;
1990
	}
1991
1992
	// This can get really nasty... therefore we only do the last six months
1993
	$get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60);
1994
1995
	// Select forum ids, do not include categories
1996
	$sql = 'SELECT forum_id
1997
		FROM ' . FORUMS_TABLE . '
1998
		WHERE forum_type <> ' . FORUM_CAT;
1999
	$result = $db->sql_query($sql);
2000
2001
	$forum_ids = array();
2002
	while ($row = $db->sql_fetchrow($result))
2003
	{
2004
		$forum_ids[] = $row['forum_id'];
2005
	}
2006
	$db->sql_freeresult($result);
2007
2008
	// Any global announcements? ;)
2009
	$forum_ids[] = 0;
2010
2011
	// Now go through the forums and get us some topics...
2012
	foreach ($forum_ids as $forum_id)
2013
	{
2014
		$sql = 'SELECT p.poster_id, p.topic_id
2015
			FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t
2016
			WHERE t.forum_id = ' . $forum_id . '
2017
				AND t.topic_moved_id = 0
2018
				AND t.topic_last_post_time > ' . $get_from_time . '
2019
				AND t.topic_id = p.topic_id
2020
				AND p.poster_id <> ' . ANONYMOUS . '
2021
			GROUP BY p.poster_id, p.topic_id';
2022
		$result = $db->sql_query($sql);
2023
2024
		$posted = array();
2025
		while ($row = $db->sql_fetchrow($result))
2026
		{
2027
			$posted[$row['poster_id']][] = $row['topic_id'];
2028
		}
2029
		$db->sql_freeresult($result);
2030
2031
		$sql_ary = array();
2032
		foreach ($posted as $user_id => $topic_row)
2033
		{
2034
			foreach ($topic_row as $topic_id)
2035
			{
2036
				$sql_ary[] = array(
2037
					'user_id'		=> (int) $user_id,
2038
					'topic_id'		=> (int) $topic_id,
2039
					'topic_posted'	=> 1,
2040
				);
2041
			}
2042
		}
2043
		unset($posted);
2044
2045
		if (sizeof($sql_ary))
2046
		{
2047
			$db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
2048
		}
2049
	}
2050
}
2051
2052
/**
2053
* Ensure that all users have a default group specified and update related information such as their colour
2054
*/
2055
function fix_empty_primary_groups()
2056
{
2057
	global $db;
2058
2059
	// Set group ids for users not already having it
2060
	$sql = 'UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('registered') . '
2061
		WHERE group_id = 0 AND user_type = ' . USER_INACTIVE;
2062
	$db->sql_query($sql);
2063
2064
	$sql = 'UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('registered') . '
2065
		WHERE group_id = 0 AND user_type = ' . USER_NORMAL;
2066
	$db->sql_query($sql);
2067
2068
	$db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('guests') . ' WHERE user_id = ' . ANONYMOUS);
2069
2070
	$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('administrators');
2071
	$result = $db->sql_query($sql);
2072
2073
	$user_ids = array();
2074
	while ($row = $db->sql_fetchrow($result))
2075
	{
2076
		$user_ids[] = $row['user_id'];
2077
	}
2078
	$db->sql_freeresult($result);
2079
2080
	if (sizeof($user_ids))
2081
	{
2082
		$db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('administrators') . '
2083
			WHERE group_id = 0 AND ' . $db->sql_in_set('user_id', $user_ids));
2084
	}
2085
2086
	$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('global_moderators');
2087
2088
	$user_ids = array();
2089
	while ($row = $db->sql_fetchrow($result))
2090
	{
2091
		$user_ids[] = $row['user_id'];
2092
	}
2093
	$db->sql_freeresult($result);
2094
2095
	if (sizeof($user_ids))
2096
	{
2097
		$db->sql_query('UPDATE ' . USERS_TABLE . ' SET group_id = ' . get_group_id('global_moderators') . '
2098
			WHERE group_id = 0 AND ' . $db->sql_in_set('user_id', $user_ids));
2099
	}
2100
2101
	// Set user colour
2102
	$sql = 'SELECT group_id, group_colour FROM ' . GROUPS_TABLE . "
2103
		WHERE group_colour <> ''";
2104
	$result = $db->sql_query($sql);
2105
2106
	while ($row = $db->sql_fetchrow($result))
2107
	{
2108
		$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_colour = '{$row['group_colour']}' WHERE group_id = {$row['group_id']}");
2109
	}
2110
	$db->sql_freeresult($result);
2111
}
2112
2113
/**
2114
* Cleanly remove invalid user entries after converting the users table...
2115
*/
2116
function remove_invalid_users()
2117
{
2118
	global $convert, $db, $phpEx, $phpbb_root_path;
2119
2120
	// username_clean is UNIQUE
2121
	$sql = 'SELECT user_id
2122
		FROM ' . USERS_TABLE . "
2123
		WHERE username_clean = ''";
2124
	$result = $db->sql_query($sql);
2125
	$row = $db->sql_fetchrow($result);
2126
	$db->sql_freeresult($result);
2127
2128
	if ($row)
2129
	{
2130
		if (!function_exists('user_delete'))
2131
		{
2132
			include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
2133
		}
2134
2135
		user_delete('remove', $row['user_id']);
2136
	}
2137
}
2138
2139
function convert_bbcode($message, $convert_size = true, $extended_bbcodes = false)
2140
{
2141
	static $orig, $repl, $origx, $replx, $str_from, $str_to;
2142
2143
	if (empty($orig))
2144
	{
2145
		$orig = $repl = array();
2146
2147
		$orig[] = '#\[(php|sql)\](.*?)\[/(php|sql)\]#is';
2148
		$repl[] = '[code]\2[/code]';
2149
2150
		$orig[] = '#\[font=[^\]]+\](.*?)\[/font\]#is';
2151
		$repl[] = '\1';
2152
2153
		$orig[] = '#\[align=[a-z]+\](.*?)\[/align\]#is';
2154
		$repl[] = '\1';
2155
2156
		$orig[] = '#\[/list=.*?\]#is';
2157
		$repl[] = '[/list]';
2158
2159
		$origx = array(
2160
			'#\[glow[^\]]+\](.*?)\[/glow\]#is',
2161
			'#\[shadow[^\]]+\](.*?)\[/shadow\]#is',
2162
			'#\[flash[^\]]+\](.*?)\[/flash\]#is'
2163
		);
2164
2165
		$replx = array(
2166
			'\1',
2167
			'\1',
2168
			'[url=\1]Flash[/url]'
2169
		);
2170
2171
		$str_from = array(
2172
			'[ftp]',	'[/ftp]',
2173
			'[ftp=',	'[/ftp]',
2174
			'[pre]',	'[/pre]',
2175
			'[table]',	'[/table]',
2176
			'[td]',		'[/td]',
2177
			'[tr]',		'[/tr]',
2178
			'[s]',		'[/s]',
2179
			'[left]',	'[/left]',
2180
			'[right]',	'[/right]',
2181
			'[center]',	'[/center]',
2182
			'[sub]',	'[/sub]',
2183
			'[sup]',	'[/sup]',
2184
			'[tt]',		'[/tt]',
2185
			'[move]',	'[/move]',
2186
			'[hr]'
2187
		);
2188
2189
		$str_to = array(
2190
			'[url]',	'[/url]',
2191
			'[url=',	'[/url]',
2192
			'[code]',	'[/code]',
2193
			"\n",		'',
2194
			'',			'',
2195
			"\n",		'',
2196
			'',			'',
2197
			'',			'',
2198
			'',			'',
2199
			'',			'',
2200
			'',			'',
2201
			'',			'',
2202
			'',			'',
2203
			'',			'',
2204
			"\n\n"
2205
		);
2206
2207
		for ($i = 0; $i < sizeof($str_from); ++$i)
2208
		{
2209
			$origx[] = '#\\' . str_replace(']', '\\]', $str_from[$i]) . '#is';
2210
			$replx[] = $str_to[$i];
2211
		}
2212
	}
2213
2214
	if (preg_match_all('#\[email=([^\]]+)\](.*?)\[/email\]#i', $message, $m))
2215
	{
2216
		for ($i = 0; $i < sizeof($m[1]); ++$i)
2217
		{
2218
			if ($m[1][$i] == $m[2][$i])
2219
			{
2220
				$message = str_replace($m[0][$i], '[email]' . $m[1][$i] . '[/email]', $message);
2221
			}
2222
			else
2223
			{
2224
				$message = str_replace($m[0][$i], $m[2][$i] . ' ([email]' . $m[1][$i] . '[/email])', $message);
2225
			}
2226
		}
2227
	}
2228
2229
	if ($convert_size && preg_match('#\[size=[0-9]+\].*?\[/size\]#i', $message))
2230
	{
2231
		$size = array(9, 9, 12, 15, 18, 24, 29, 29, 29, 29);
2232
		$message = preg_replace('#\[size=([0-9]+)\](.*?)\[/size\]#i', '[size=\1]\2[/size]', $message);
2233
		$message = preg_replace('#\[size=[0-9]{2,}\](.*?)\[/size\]#i', '[size=29]\1[/size]', $message);
2234
2235
		for ($i = sizeof($size); $i; )
2236
		{
2237
			$i--;
2238
			$message = str_replace('[size=' . $i . ']', '[size=' . $size[$i] . ']', $message);
2239
		}
2240
	}
2241
2242
	if ($extended_bbcodes)
2243
	{
2244
		$message = preg_replace($origx, $replx, $message);
2245
	}
2246
2247
	$message = preg_replace($orig, $repl, $message);
2248
	return $message;
2249
}
2250
2251
2252
function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
2253
{
2254
	global $convert, $phpbb_root_path, $config, $user, $db;
2255
2256
	if (substr($trg, -1) == '/')
2257
	{
2258
		$trg .= basename($src);
2259
	}
2260
	$src_path = relative_base($src, $source_relative_path, __LINE__, __FILE__);
2261
	$trg_path = $trg;
2262
2263
	if (!$overwrite && @file_exists($trg_path))
2264
	{
2265
		return true;
2266
	}
2267
2268
	if (!@file_exists($src_path))
2269
	{
2270
		return;
2271
	}
2272
2273
	$path = $phpbb_root_path;
2274
	$parts = explode('/', $trg);
2275
	unset($parts[sizeof($parts) - 1]);
2276
2277
	for ($i = 0; $i < sizeof($parts); ++$i)
2278
	{
2279
		$path .= $parts[$i] . '/';
2280
2281
		if (!is_dir($path))
2282
		{
2283
			@mkdir($path, 0777);
2284
		}
2285
	}
2286
2287
	if (!is_writable($path))
2288
	{
2289
		@chmod($path, 0777);
2290
	}
2291
2292
	if (!@copy($src_path, $phpbb_root_path . $trg_path))
2293
	{
2294
		$convert->p_master->error(sprintf($user->lang['COULD_NOT_COPY'], $src_path, $phpbb_root_path . $trg_path), __LINE__, __FILE__, !$die_on_failure);
2295
		return;
2296
	}
2297
2298
	if ($perm = @fileperms($src_path))
2299
	{
2300
		@chmod($phpbb_root_path . $trg_path, $perm);
2301
	}
2302
2303
	return true;
2304
}
2305
2306
function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
2307
{
2308
	global $convert, $phpbb_root_path, $config, $user, $db;
2309
2310
	$dirlist = $filelist = $bad_dirs = array();
2311
	$src = path($src, $source_relative_path);
2312
	$trg = path($trg);
2313
	$src_path = relative_base($src, $source_relative_path, __LINE__, __FILE__);
2314
	$trg_path = $phpbb_root_path . $trg;
2315
2316
	if (!is_dir($trg_path))
2317
	{
2318
		@mkdir($trg_path, 0777);
2319
		@chmod($trg_path, 0777);
2320
	}
2321
2322
	if (!@is_writable($trg_path))
2323
	{
2324
		$bad_dirs[] = path($config['script_path']) . $trg;
2325
	}
2326
2327
	if ($handle = @opendir($src_path))
2328
	{
2329
		while ($entry = readdir($handle))
2330
		{
2331
			if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
2332
			{
2333
				continue;
2334
			}
2335
2336
			if (is_dir($src_path . $entry))
2337
			{
2338
				$dirlist[] = $entry;
2339
			}
2340
			else
2341
			{
2342
				$filelist[] = $entry;
2343
			}
2344
		}
2345
		closedir($handle);
2346
	}
2347
	else if ($dir = @dir($src_path))
2348
	{
2349
		while ($entry = $dir->read())
2350
		{
2351
			if ($entry[0] == '.' || $entry == 'CVS' || $entry == 'index.htm')
2352
			{
2353
				continue;
2354
			}
2355
2356
			if (is_dir($src_path . $entry))
2357
			{
2358
				$dirlist[] = $entry;
2359
			}
2360
			else
2361
			{
2362
				$filelist[] = $entry;
2363
			}
2364
		}
2365
		$dir->close();
2366
	}
2367
	else
2368
	{
2369
		$convert->p_master->error(sprintf($user->lang['CONV_ERROR_COULD_NOT_READ'], relative_base($src, $source_relative_path)), __LINE__, __FILE__);
2370
	}
2371
2372
	if ($copy_subdirs)
2373
	{
2374
		for ($i = 0; $i < sizeof($dirlist); ++$i)
2375
		{
2376
			$dir = $dirlist[$i];
2377
2378
			if ($dir == 'CVS')
2379
			{
2380
				continue;
2381
			}
2382
2383
			if (!is_dir($trg_path . $dir))
2384
			{
2385
				@mkdir($trg_path . $dir, 0777);
2386
				@chmod($trg_path . $dir, 0777);
2387
			}
2388
2389
			if (!@is_writable($trg_path . $dir))
2390
			{
2391
				$bad_dirs[] = $trg . $dir;
2392
				$bad_dirs[] = $trg_path . $dir;
2393
			}
2394
2395
			if (!sizeof($bad_dirs))
2396
			{
2397
				copy_dir($src . $dir, $trg . $dir, true, $overwrite, $die_on_failure, $source_relative_path);
2398
			}
2399
		}
2400
	}
2401
2402
	if (sizeof($bad_dirs))
2403
	{
2404
		$str = (sizeof($bad_dirs) == 1) ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
2405
		sort($bad_dirs);
2406
		$convert->p_master->error(sprintf($str, implode('<br />', $bad_dirs)), __LINE__, __FILE__);
2407
	}
2408
2409
	for ($i = 0; $i < sizeof($filelist); ++$i)
2410
	{
2411
		copy_file($src . $filelist[$i], $trg . $filelist[$i], $overwrite, $die_on_failure, $source_relative_path);
2412
	}
2413
}
2414
2415
function relative_base($path, $is_relative = true, $line = false, $file = false)
2416
{
2417
	global $convert, $phpbb_root_path, $config, $user, $db;
2418
2419
	if (!$is_relative)
2420
	{
2421
		return $path;
2422
	}
2423
2424
	if (empty($convert->options['forum_path']) && $is_relative)
2425
	{
2426
		$line = $line ? $line : __LINE__;
2427
		$file = $file ? $file : __FILE__;
2428
2429
		$convert->p_master->error($user->lang['CONV_ERROR_NO_FORUM_PATH'], $line, $file);
2430
	}
2431
2432
	return $convert->options['forum_path'] . '/' . $path;
2433
}
2434
2435
function get_smiley_display()
2436
{
2437
	static $smiley_count = 0;
2438
	$smiley_count++;
2439
	return ($smiley_count < 50) ? 1 : 0;
2440
}
2441
2442
2443
function fill_dateformat($user_dateformat)
2444
{
2445
	global $config;
2446
	
2447
	return ((empty($user_dateformat)) ? $config['default_dateformat'] : $user_dateformat);
2448
}
2449
2450
2451
2452
?>