source: trunk/forum/includes/functions_convert.php

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