IPB3_4::preparseBoards()   B
last analyzed

Complexity

Conditions 6
Paths 10

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 23
c 0
b 0
f 0
nc 10
nop 1
dl 0
loc 40
rs 8.9297
1
<?php
2
/**
3
 * @name      OpenImporter
4
 * @copyright OpenImporter contributors
5
 * @license   BSD https://opensource.org/licenses/BSD-3-Clause
6
 *
7
 * @version 1.0
8
 */
9
10
/**
11
 * Class IPB3_4
12
 * Settings for the IPB3_4 system.
13
 */
14
class IPB3_4 extends Importers\AbstractSourceImporter
15
{
16
	protected $setting_file = '/conf_global.php';
17
18
	/**
19
	 * The id of the disabled (?) members group.
20
	 * @var int|bool
21
	 */
22
	protected $is_disabled = false;
23
24
	/**
25
	 * The id of the banned members group.
26
	 * @var int|bool
27
	 */
28
	protected $is_banned = false;
29
	protected $groupsTranslation = null;
30
	protected $permissionGroupsTranslation = null;
31
32
	public function getName()
33
	{
34
		return 'IPB3_4';
35
	}
36
37
	public function getVersion()
38
	{
39
		return '1.0';
40
	}
41
42
	public function getPrefix()
43
	{
44
		global $config;
45
46
		return '`' . $this->getDbName() . '`.' . $config['database']['table_prefix'];
47
	}
48
49
	public function setDefines()
50
	{
51
	}
52
53
	public function dbConnectionData()
54
	{
55
		if ($this->path === null)
56
			return false;
57
58
		return array(
59
			'dbname' => $this->fetchSetting('sql_database'),
60
			'user' => $this->fetchSetting('sql_user'),
61
			'password' => $this->fetchSetting('sql_pass'),
62
			'host' => $this->fetchSetting('sql_host'),
63
			'driver' => 'pdo_mysql',  // As far as I can tell IPB is MySQL only
64
			'test_table' => $this->getTableTest(),
65
			'system_name' => $this->getName(),
66
		);
67
	}
68
69
	public function getTableTest()
70
	{
71
		return '{db_prefix}members';
72
	}
73
74
	public function getDbPrefix()
75
	{
76
		$db_name = $this->getDbName();
77
		$db_prefix = $this->fetchSetting('sql_tbl_prefix');
78
		return '`' . $db_name . '`.' . $db_prefix;
79
	}
80
81
	public function getDbName()
82
	{
83
		return $this->fetchSetting('sql_database');
84
	}
85
86
	public function fetchSetting($name)
87
	{
88
		$content = $this->readSettingsFile();
0 ignored issues
show
Bug introduced by
The method readSettingsFile() does not exist on IPB3_4. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

88
		/** @scrutinizer ignore-call */ 
89
  $content = $this->readSettingsFile();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
89
90
		$match = array();
91
		preg_match('~\$INFO\[\'' . $name . '\'\]\s*=\s*\'(.*?)\';~', $content, $match);
92
93
		return $match[1] ?? '';
94
	}
95
96
	protected function html2bbc($text)
97
	{
98
		$text = preg_replace(
99
			array(
100
				'~<!--QuoteBegin.*?-->.+?<!--QuoteEBegin-->~is',
101
				'~<!--QuoteEnd-->.+?<!--QuoteEEnd-->~is',
102
				'~<!--quoteo\(post=(.+?):date=(.+?):name=(.+?)\)-->.+?<!--quotec-->~is',
103
				'~<!--quoteo-->.+?<!--quotec-->~is',
104
				'~<blockquote .+? data-author="(.+?)" data-cid="(.+?)" data-time="(.+?)">~is',
105
				'~</blockquote>~is',
106
				'~<!--c1-->.+?<!--ec1-->~is',
107
				'~<!--c2-->.+?<!--ec2-->~is',
108
				'~<!--coloro:.+?--><span style=\'color:([^;]+?)\'><!--/coloro-->~is',
109
				'~<!--coloro:.+?--><span style="color:([^;]+?)"><!--/coloro-->~is',
110
				'~<!--colorc--></span><!--/colorc-->~is',
111
				'~<!--fonto:.+?><span style=\'font-family:([^;]+?)\'><!--/fonto-->~is',
112
				'~<!--fonto:.+?><span style="font-family:([^;]+?)"><!--/fonto-->~is',
113
				'~<!--fontc--></span><!--/fontc-->~is',
114
				'~<!--sizeo:.+?><span style=\'font-size:([^;]+?)\'><!--/sizeo-->~is',
115
				'~<!--sizeo:.+?><span style="font-size:([^;]+?)"><!--/sizeo-->~is',
116
				'~<!--sizeo:.+?><span style="font-size:([^;]+?);line-height:100%"><!--/sizeo-->~is',
117
				'~<!--sizec--></span><!--/sizec-->~is',
118
				'~<([/]?)ul>~is',
119
				'~<ol type=\'a\'>~s',
120
				'~<ol type=\'A\'>~s',
121
				'~<ol type=\'1\'>~s',
122
				'~<ol type=\'i\'>~s',
123
				'~<ol type=\'I\'>~s',
124
				'~</ol>~is',
125
				'~<img src=".+?" style="vertical-align:middle" emoid=".+?" border="0" alt="(.+?)" />~i',
126
				'~<img src=\'~i',
127
				'~\' border=\'0\' alt=\'(.+?)\'( /)?' . '>~i',
128
				'~<img src="~i',
129
				'~" border="0" alt="(.+?)"( /)?' . '>~i',
130
				'~<!--emo&(.+?)-->.+?<!--endemo-->~i',
131
				'~<strike>.+?</strike>~is',
132
				'~<a href="mailto:.+?">.+?</a>~is',
133
				'~<a href="(.+?)" target="_blank">(.+?)</a>~is',
134
				'~<a href=\'(.+?)\' target=\'_blank\'>(.+?)</a>~is',
135
				'~<p>(.+?)</p>~is',
136
				'~<div>(.+?)</div>~is',
137
			),
138
			array(
139
				'[quote]',
140
				'[/quote]',
141
				'[quote=$3]',
142
				'[quote]',
143
				'[quote author=$1 link=msg=$2 date=$3]',
144
				'[/quote]',
145
				'[code]',
146
				'[/code]',
147
				'[color=$1]',
148
				'[color=$1]',
149
				'[/color]',
150
				'[font=$1]',
151
				'[font=$1]',
152
				'[/font]',
153
				'[size=$1]',
154
				'[size=$1]',
155
				'[size=$1]',
156
				'[/size]',
157
				'[$1list]',
158
				'[list type=lower-alpha]',
159
				'[list type=upper-alpha]',
160
				'[list type=decimal]',
161
				'[list type=lower-roman]',
162
				'[list type=upper-roman]',
163
				'[/list]',
164
				'$2',
165
				'[img]',
166
				'[/img]',
167
				'[img]',
168
				'[/img]',
169
				'$1',
170
				'[s]$1[/s]',
171
				'[email=$1]$2[/email]',
172
				'[url=$1]$2[/url]',
173
				'[url=$1]$2[/url]',
174
				'$1<br />',
175
				'$1<br />',
176
			), ltrim(stripslashes($text)));
177
		return strtr(strtr($text, '<>', '[]'), array('[br /]' => '<br />'));
178
	}
179
180
	protected function additionalGroups($string)
181
	{
182
		$temp = explode(',', $string);
183
		$groups = array();
184
		foreach ($temp as $grp)
185
		{
186
			$groups[] = $this->mapGroups($grp);
187
		}
188
		$groups = array_filter($groups, static function($val) { return $val !== false; });
189
		return implode(',', array_unique($groups));
190
	}
191
192
	protected function mapGroups($group_id)
193
	{
194
		$this->createGroupsTranslation();
195
196
		if (empty($group_id))
197
			return;
198
199
		if (isset($this->groupsTranslation[$group_id]))
200
			$group = $this->groupsTranslation[$group_id];
201
		elseif ($group_id > 5)
202
			$group = $group_id + 3;
203
		else
204
			$group = $group_id;
205
206
		return $group;
207
	}
208
209
	protected function createGroupsTranslation()
210
	{
211
		if ($this->groupsTranslation !== null)
212
			return;
213
214
		$this->groupsTranslation = array(
215
// 		$this->fetchSetting('banned_group') => ???,
216
			$this->fetchSetting('admin_group') => 1,
217
			$this->fetchSetting('guest_group') => -1,
218
			$this->fetchSetting('member_group') => 0,
219
// 			$this->fetchSetting('auth_group') => 1,
220
		);
221
		$this->is_banned = (int) $this->fetchSetting('banned_group');
222
		$this->is_disabled = (int) $this->fetchSetting('auth_group');
223
	}
224
225
	protected function mapPermissionGroups($group_id)
226
	{
227
		$this->createPermissionGroupsTranslation();
228
229
		if (empty($group_id))
230
			return;
231
232
		if (isset($this->permissionGroupsTranslation[$group_id]))
233
			$group = $this->permissionGroupsTranslation[$group_id];
234
		elseif ($group_id > 5)
235
			$group = $group_id + 3;
236
		else
237
			$group = $group_id;
238
239
		return $group;
240
	}
241
242
	protected function createPermissionGroupsTranslation()
243
	{
244
		if ($this->permissionGroupsTranslation !== null)
245
			return;
246
247
		$known = array(
248
// 			'Validating Forum Set' => ???,
249
			'Member Forum Set' => 0,
250
			'Guest Forum Set' => -1,
251
			'Admin Forum Set' => 1,
252
			'Banned Forum Set' => 3,
253
			'Moderator Forum Set' => 2,
254
		);
255
256
		$result = $this->db->query("
257
			SELECT perm_id, perm_name
258
			FROM {$this->config->from_prefix}forum_perms");
259
260
		$this->permissionGroupsTranslation = array();
261
		// We want to stay on the safe side: either set it to a group we know, or admin-only
262
		while ($row = $this->db->fetch_assoc($result))
263
			$this->permissionGroupsTranslation[$row['perm_id']] = $known[$row['perm_name']] ?? 1;
264
		$this->db->free_result($result);
265
	}
266
267
	protected function getAttachDir()
268
	{
269
		$result = $this->db->query("
270
			SELECT conf_value
271
			FROM {$this->config->from_prefix}core_sys_conf_settings
272
			WHERE conf_key = 'upload_dir'
273
			LIMIT 1");
274
		list ($attach_dir) = $this->db->fetch_row($result);
275
		$this->db->free_result($result);
276
277
		return $attach_dir;
278
	}
279
280
	/**
281
	 * From here on, all the methods are needed helper for the conversion
282
	 */
283
	public function preparseMembers($originalRows)
284
	{
285
		$rows = array();
286
287
		$this->createGroupsTranslation();
288
289
		foreach ($originalRows as $row)
290
		{
291
			// @todo check avatars conversion
292
			// @todo find a way to port titles (post-based groups)
293
			// @todo warn_level what is the value?
294
295
			$row['signature'] = $this->html2bbc($row['signature']);
296
297
			$row['additional_groups'] = $this->additionalGroups($row['additional_groups']);
298
299
			$row['date_registered'] = date('Y-m-d G:i:s', $row['date_registered']);
300
301
			// @todo verify
302
			if ($this->is_disabled === (int) $row['id_group'])
303
				$row['is_activated'] = 0;
304
305
			if ($this->is_banned === (int) $row['id_group'])
306
				$row['is_activated'] = $row['is_activated'] + 10;
307
308
			$row['id_group'] = $this->mapGroups($row['id_group']);
309
310
			// That's pretty much a guess, @todo verify!
311
			if (!empty($row['pm_ignore_list']))
312
				$row['pm_ignore_list'] = implode(',', unserialize($row['pm_ignore_list']));
313
314
			$rows[] = $row;
315
		}
316
317
		return $rows;
318
	}
319
320
	public function preparseMessages($originalRows)
321
	{
322
		$rows = array();
323
324
		foreach ($originalRows as $row)
325
		{
326
			$row['body'] = $this->html2bbc($row['body']);
327
328
			$rows[] = $row;
329
		}
330
331
		return $rows;
332
	}
333
334
	public function preparseAttachments($originalRows)
335
	{
336
		$rows = array();
337
		$attach_dir = $this->getAttachDir();
338
339
		foreach ($originalRows as $row)
340
		{
341
			$row['full_path'] = $attach_dir . '/' . dirname($row['attach_location']);
342
			$row['system_filename'] = basename($row['attach_location']);
343
			unset($row['attach_location']);
344
345
			$rows[] = $row;
346
		}
347
348
		return $rows;
349
	}
350
351
	public function preparseBoards($originalRows)
352
	{
353
		$rows = array();
354
		$request = $this->db->query("
355
			SELECT id AS id_cat
356
			FROM {$this->config->from_prefix}forums
357
			WHERE parent_id = -1");
358
359
		$cats = array();
360
		while ($row = $this->db->fetch_assoc($request))
361
			$cats[] = $row['id_cat'];
362
		$this->db->free_result($request);
363
364
		foreach ($originalRows as $row)
365
		{
366
			if ($row['perm_view'] == '*')
367
			{
368
				$this->createPermissionGroupsTranslation();
369
				$groups = $this->permissionGroupsTranslation;
370
			}
371
			else
372
			{
373
				$perm_view = array_filter(explode(',', $row['perm_view']));
374
				$groups = array();
375
				foreach ($perm_view as $perm)
376
					$groups[] = $this->mapPermissionGroups($perm);
377
			}
378
			unset($row['perm_view']);
379
			$row['member_groups'] = implode(',', array_unique($groups));
380
381
			if (isset($cats[$row['id_parent']]))
382
			{
383
				$row['id_cat'] = $cats[$row['id_parent']];
384
				$row['id_parent'] = 0;
385
			}
386
387
			$rows[] = $row;
388
		}
389
390
		return $rows;
391
	}
392
393
	public function preparseTopics($originalRows)
394
	{
395
		$rows = array();
396
397
		foreach ($originalRows as $row)
398
		{
399
			$request = $this->db->query("
400
				SELECT COUNT(*)
401
				FROM {$this->config->from_prefix}posts
402
				WHERE topic_id = $row[id_topic]
403
					AND queued = 1");
404
			list ($unapproved) = $this->db->fetch_row($request);
405
			$this->db->free_result($request);
406
407
			$row['unapproved_posts'] = (int) $unapproved;
408
409
			$row['approved'] = min($row['approved'], 3);
410
			$row['id_poll'] = (int) $row['id_poll'];
411
412
			$rows[] = $row;
413
		}
414
415
		return $rows;
416
	}
417
418
	public function preparsePolloptions($originalRows)
419
	{
420
		$rows = array();
421
422
		foreach ($originalRows as $row)
423
		{
424
			$choices = @unserialize(stripslashes($row['choices']));
425
426
			if (is_array($choices))
427
			{
428
				foreach ($choices as $choice)
429
				{
430
					// Put the slashes back
431
					$choice = Strings::addslashes_recursive($choice);
0 ignored issues
show
Bug introduced by
The type Strings was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
432
433
					// Now go ahead with our choices and votes
434
					foreach($choice['choice'] AS $choiceid => $label)
435
					{
436
						// The keys of the id_choice array correspond to the keys of the choice array,
437
						// which are the id_choice values
438
						$votes = $choice['votes'][$choiceid];
439
440
						// @todo: try to work around the multiple-questions-per-poll issue...
441
/*						if(isset($current_choices[$row['id_poll']][$choiceid]))
442
							continue;
443
						else
444
							$current_choices[$row['id_poll']][$choiceid] = $label;*/
445
446
						// Finally - a row of information!
447
						$rows[] = array(
448
							'id_poll' => $row['pid'],
449
							'id_choice' => $choiceid,
450
							'label' => addslashes($label),
451
							'votes' => $votes,
452
						);
453
					}
454
				}
455
			}
456
		}
457
458
		return $rows;
459
	}
460
461
	public function preparsePollvotes($originalRows)
462
	{
463
		$rows = array();
464
465
		foreach ($originalRows as $row)
466
		{
467
			$choices = @unserialize($row['member_choices']);
468
469
			if (is_array($choices))
470
			{
471
				foreach ($choices as $pid => $pchoices)
472
				{
473
					if ($row['id_poll'] != $pid)
474
						continue;
475
476
					foreach ($pchoices as $choice)
477
					{
478
						// Finally - a row of information!
479
						$rows[] = array(
480
							'id_poll' => $row['id_poll'],
481
							'id_member' => $row['id_member'],
482
							'id_choice' => $choice,
483
						);
484
					}
485
				}
486
			}
487
		}
488
489
		return $rows;
490
	}
491
492
	public function preparsePm($originalRows)
493
	{
494
		$rows = array();
495
496
		foreach ($originalRows as $row)
497
		{
498
			$row['body'] = $this->html2bbc($row['body']);
499
500
			$rows[] = $row;
501
		}
502
503
		return $rows;
504
	}
505
506
	public function preparsePmrecipients($originalRows)
507
	{
508
		$rows = array();
509
510
		foreach ($originalRows as $row)
511
		{
512
			$invited_members = @unserialize($row['mt_invited_members']);
513
514
			$rows[] = array(
515
				'id_pm' => $row['id_pm'],
516
				'id_member' => ($row['msg_author_id'] == $row['id_member']) ? $row['mt_starter_id'] : $row['id_member'],
517
				'labels' => $row['labels'],
518
				'is_read' => $row['is_read'],
519
			);
520
521
			if (is_array($invited_members) && !empty($invited_members))
522
			{
523
				foreach ($invited_members as $invited => $id)
524
				{
525
					if (!empty($invited))
526
					{
527
						$rows[] = array(
528
							'id_pm' => $row['id_pm'],
529
							'id_member' => ($row['msg_author_id'] == $id) ? $row['mt_starter_id'] : $id,
530
							'labels' => $row['labels'],
531
							'is_read' => $row['is_read'],
532
						);
533
					}
534
				}
535
			}
536
		}
537
538
		return $rows;
539
	}
540
541
	public function preparseBoardmods($originalRows)
542
	{
543
		$rows = array();
544
545
		foreach ($originalRows as $row)
546
		{
547
			if (!empty($row['id_member']))
548
				$rows[] = $row;
549
		}
550
551
		return $rows;
552
	}
553
554
	public function codeCopysmiley()
555
	{
556
		$source_base_dir = $this->config->path_from . '/public/style_emoticons';
557
558
		if (!empty($source_base_dir) && file_exists($source_base_dir))
559
		{
560
			$request = $this->db->query("
561
				SELECT image, emo_set
562
				FROM {$this->config->from_prefix}emoticons
563
				WHERE variable = 'smileys_dir';");
564
565
			$smiley = array();
566
			while ($row = $this->db->fetch_assoc($request))
567
			{
568
				if (file_exists($source_base_dir . '/' . $row['emo_set'] . '/' . $row['image']))
569
				{
570
					$smiley[] = array(
571
						'basedir' => $source_base_dir,
572
						'full_path' => $source_base_dir . '/' . $row['emo_set'],
573
						'filename' => $row['image'],
574
					);
575
				}
576
			}
577
		}
578
579
		if (!empty($smiley))
580
			return array($smiley);
581
		else
582
			return false;
583
	}
584
585
	public function preparseCustomfields($originalRows)
586
	{
587
		$rows = array();
588
589
		foreach ($originalRows as $row)
590
		{
591
			if ($row['field_type'] == 'drop')
592
				$row['field_type'] = 'select';
593
594
			if (!empty($row['field_options']))
595
			{
596
				$options = explode('|', $row['field_options']);
597
				$row['field_options'] = array();
598
				foreach ($options as $option)
599
				{
600
					list($key, $val) = explode('=', $option);
601
					$row['field_options'][$key] = $val;
602
				}
603
			}
604
605
			if (empty($row['pf_member_hide']) && !empty($row['pf_member_edit']) && empty($row['pf_admin_only']))
606
				$row['private'] = 0;
607
			elseif (!empty($row['pf_member_hide']) && empty($row['pf_member_edit']) && !empty($row['pf_admin_only']))
608
				$row['private'] = 3;
609
			// @todo this is dubious, probably pf_admin_only should be empty as well (or ignored)
610
			elseif (empty($row['pf_member_hide']) && (empty($row['pf_member_edit']) || !empty($row['pf_admin_only'])))
611
				$row['private'] = 1;
612
			elseif (!empty($row['pf_member_hide']) && !empty($row['pf_member_edit']) && empty($row['pf_admin_only']))
613
				$row['private'] = 2;
614
			// In case we don't know: most restrictive
615
			else
616
				$row['private'] = 3;
617
618
			unset($row['pf_member_hide'], $row['pf_member_edit'], $row['pf_admin_only']);
619
620
			$rows[] = $row;
621
		}
622
623
		return $rows;
624
	}
625
626
	public function preparseCustomfieldsdata($originalRows)
627
	{
628
		$rows = array();
629
		$fields = array();
630
631
		$request = $this->db->query("
632
			SELECT pf_id, pf_key
633
			FROM {$this->config->from_prefix}pfields_data");
634
635
		while ($row = $this->db->fetch_assoc($request))
636
			$fields[$row['pf_id']] = $row;
637
638
		foreach ($originalRows as $row)
639
		{
640
			foreach ($row as $key => $val)
641
			{
642
				if (substr($key, 0, 5) == 'field')
643
				{
644
					$rows[] = array(
645
						'id_member' => $row['member_id'],
646
						'variable' => $fields[substr($key, 6)]['pf_key'],
647
						'value' => $val,
648
					);
649
				}
650
			}
651
		}
652
653
		return $rows;
654
	}
655
}
656