~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 acp
5
* @version $Id: acp_styles.php,v 1.117 2007/10/21 11:26:24 acydburn Exp $
6
* @copyright (c) 2005 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
* @package acp
21
*/
22
class acp_styles
23
{
24
	var $u_action;
25
26
	var $style_cfg;
27
	var $template_cfg;
28
	var $theme_cfg;
29
	var $imageset_cfg;
30
	var $imageset_keys;
31
32
	function main($id, $mode)
33
	{
34
		global $db, $user, $auth, $template, $cache;
35
		global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
36
37
		// Hardcoded template bitfield to add for new templates
38
		$bitfield = new bitfield();
39
		$bitfield->set(0);
40
		$bitfield->set(3);
41
		$bitfield->set(8);
42
		$bitfield->set(9);
43
		$bitfield->set(11);
44
		$bitfield->set(12);
45
		define('TEMPLATE_BITFIELD', $bitfield->get_base64());
46
		unset($bitfield);
47
48
		$user->add_lang('acp/styles');
49
50
		$this->tpl_name = 'acp_styles';
51
		$this->page_title = 'ACP_CAT_STYLES';
52
53
		$action = request_var('action', '');
54
		$action = (isset($_POST['add'])) ? 'add' : $action;
55
		$style_id = request_var('id', 0);
56
57
		// Fill the configuration variables
58
		$this->style_cfg = $this->template_cfg = $this->theme_cfg = $this->imageset_cfg = '
59
#
60
# phpBB {MODE} configuration file
61
#
62
# @package phpBB3
63
# @copyright (c) 2005 phpBB Group
64
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
65
#
66
#
67
# At the left is the name, please do not change this
68
# At the right the value is entered
69
# For on/off options the valid values are on, off, 1, 0, true and false
70
#
71
# Values get trimmed, if you want to add a space in front or at the end of
72
# the value, then enclose the value with single or double quotes.
73
# Single and double quotes do not need to be escaped.
74
#
75
#
76
77
# General Information about this {MODE}
78
name = {NAME}
79
copyright = {COPYRIGHT}
80
version = {VERSION}
81
';
82
83
		$this->theme_cfg .= '
84
# Some configuration options
85
86
#
87
# You have to turn this option on if you want to use the
88
# path template variables ({T_IMAGESET_PATH} for example) within
89
# your css file.
90
# This is mostly the case if you want to use language specific
91
# images within your css file.
92
#
93
parse_css_file = {PARSE_CSS_FILE}
94
';
95
96
		$this->imageset_keys = array(
97
			'logos' => array(
98
				'site_logo',
99
			),
100
			'buttons'	=> array(
101
				'icon_back_top', 'icon_contact_aim', 'icon_contact_email', 'icon_contact_icq', 'icon_contact_jabber', 'icon_contact_msnm', 'icon_contact_pm', 'icon_contact_yahoo', 'icon_contact_www', 'icon_post_delete', 'icon_post_edit', 'icon_post_info', 'icon_post_quote', 'icon_post_report', 'icon_user_online', 'icon_user_offline', 'icon_user_profile', 'icon_user_search', 'icon_user_warn', 'button_pm_forward', 'button_pm_new', 'button_pm_reply', 'button_topic_locked', 'button_topic_new', 'button_topic_reply',
102
			),
103
			'icons'		=> array(
104
				'icon_post_target', 'icon_post_target_unread', 'icon_topic_attach', 'icon_topic_latest', 'icon_topic_newest', 'icon_topic_reported', 'icon_topic_unapproved', 'icon_friend', 'icon_foe',
105
			),
106
			'forums'	=> array(
107
				'forum_link', 'forum_read', 'forum_read_locked', 'forum_read_subforum', 'forum_unread', 'forum_unread_locked', 'forum_unread_subforum', 'subforum_read', 'subforum_unread'
108
			),
109
			'folders'	=> array(
110
				'topic_moved', 'topic_read', 'topic_read_mine', 'topic_read_hot', 'topic_read_hot_mine', 'topic_read_locked', 'topic_read_locked_mine', 'topic_unread', 'topic_unread_mine', 'topic_unread_hot', 'topic_unread_hot_mine', 'topic_unread_locked', 'topic_unread_locked_mine', 'sticky_read', 'sticky_read_mine', 'sticky_read_locked', 'sticky_read_locked_mine', 'sticky_unread', 'sticky_unread_mine', 'sticky_unread_locked', 'sticky_unread_locked_mine', 'announce_read', 'announce_read_mine', 'announce_read_locked', 'announce_read_locked_mine', 'announce_unread', 'announce_unread_mine', 'announce_unread_locked', 'announce_unread_locked_mine', 'global_read', 'global_read_mine', 'global_read_locked', 'global_read_locked_mine', 'global_unread', 'global_unread_mine', 'global_unread_locked', 'global_unread_locked_mine', 'pm_read', 'pm_unread',
111
			),
112
			'polls'		=> array(
113
				'poll_left', 'poll_center', 'poll_right',
114
			),
115
			'ui'		=> array(
116
				'upload_bar',
117
			),
118
			'user'		=> array(
119
				'user_icon1', 'user_icon2', 'user_icon3', 'user_icon4', 'user_icon5', 'user_icon6', 'user_icon7', 'user_icon8', 'user_icon9', 'user_icon10',
120
			),
121
		);
122
123
		// Execute overall actions
124
		switch ($action)
125
		{
126
			case 'delete':
127
				if ($style_id)
128
				{
129
					$this->remove($mode, $style_id);
130
					return;
131
				}
132
			break;
133
134
			case 'export':
135
				if ($style_id)
136
				{
137
					$this->export($mode, $style_id);
138
					return;
139
				}
140
			break;
141
142
			case 'install':
143
				$this->install($mode);
144
				return;
145
			break;
146
147
			case 'add':
148
				$this->add($mode);
149
				return;
150
			break;
151
152
			case 'details':
153
				if ($style_id)
154
				{
155
					$this->details($mode, $style_id);
156
					return;
157
				}
158
			break;
159
160
			case 'edit':
161
				if ($style_id)
162
				{
163
					switch ($mode)
164
					{
165
						case 'imageset':
166
							return $this->edit_imageset($style_id);
167
						case 'template':
168
							return $this->edit_template($style_id);
169
						case 'theme':
170
							return $this->edit_theme($style_id);
171
					}
172
				}
173
			break;
174
175
			case 'cache':
176
				if ($style_id)
177
				{
178
					switch ($mode)
179
					{
180
						case 'template':
181
							return $this->template_cache($style_id);
182
					}
183
				}
184
			break;
185
		}
186
187
		switch ($mode)
188
		{
189
			case 'style':
190
191
				switch ($action)
192
				{
193
					case 'activate':
194
					case 'deactivate':
195
196
						if ($style_id == $config['default_style'])
197
						{
198
							trigger_error($user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING);
199
						}
200
201
						$sql = 'UPDATE ' . STYLES_TABLE . '
202
							SET style_active = ' . (($action == 'activate') ? 1 : 0) . '
203
							WHERE style_id = ' . $style_id;
204
						$db->sql_query($sql);
205
206
						// Set style to default for any member using deactivated style
207
						if ($action == 'deactivate')
208
						{
209
							$sql = 'UPDATE ' . USERS_TABLE . '
210
								SET user_style = ' . $config['default_style'] . "
211
								WHERE user_style = $style_id";
212
							$db->sql_query($sql);
213
214
							$sql = 'UPDATE ' . FORUMS_TABLE . '
215
								SET forum_style = 0
216
								WHERE forum_style = ' . $style_id;
217
							$db->sql_query($sql);
218
						}
219
					break;
220
				}
221
222
				$this->frontend('style', array('details'), array('export', 'delete'));
223
			break;
224
225
			case 'template':
226
227
				switch ($action)
228
				{
229
					// Refresh template data stored in db and clear cache
230
					case 'refresh':
231
232
						$sql = 'SELECT *
233
							FROM ' . STYLES_TEMPLATE_TABLE . "
234
							WHERE template_id = $style_id";
235
						$result = $db->sql_query($sql);
236
						$template_row = $db->sql_fetchrow($result);
237
						$db->sql_freeresult($result);
238
239
						if (!$template_row)
240
						{
241
							trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
242
						}
243
244
						if (confirm_box(true))
245
						{
246
							$template_refreshed = '';
247
248
							// Only refresh database if the template is stored in the database
249
							if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/"))
250
							{
251
								$filelist = array('' => array());
252
253
								$sql = 'SELECT template_filename, template_mtime
254
									FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
255
									WHERE template_id = $style_id";
256
								$result = $db->sql_query($sql);
257
258
								while ($row = $db->sql_fetchrow($result))
259
								{
260
//									if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime'])
261
//									{
262
										// get folder info from the filename
263
										if (($slash_pos = strrpos($row['template_filename'], '/')) === false)
264
										{
265
											$filelist[''][] = $row['template_filename'];
266
										}
267
										else
268
										{
269
											$filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1);
270
										}
271
//									}
272
								}
273
								$db->sql_freeresult($result);
274
275
								$this->store_templates('update', $style_id, $template_row['template_path'], $filelist);
276
								unset($filelist);
277
278
								$template_refreshed = $user->lang['TEMPLATE_REFRESHED'] . '<br />';
279
								add_log('admin', 'LOG_TEMPLATE_REFRESHED', $template_row['template_name']);
280
							}
281
282
							$this->clear_template_cache($template_row);
283
284
							trigger_error($template_refreshed . $user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action));
285
						}
286
						else
287
						{
288
							confirm_box(false, ($template_row['template_storedb']) ? $user->lang['CONFIRM_TEMPLATE_REFRESH'] : $user->lang['CONFIRM_TEMPLATE_CLEAR_CACHE'], build_hidden_fields(array(
289
								'i'			=> $id,
290
								'mode'		=> $mode,
291
								'action'	=> $action,
292
								'id'		=> $style_id
293
							)));
294
						}
295
296
					break;
297
				}
298
299
				$this->frontend('template', array('edit', 'cache', 'details'), array('refresh', 'export', 'delete'));
300
			break;
301
302
			case 'theme':
303
304
				switch ($action)
305
				{
306
					// Refresh theme data stored in the database
307
					case 'refresh':
308
309
						$sql = 'SELECT *
310
							FROM ' . STYLES_THEME_TABLE . "
311
							WHERE theme_id = $style_id";
312
						$result = $db->sql_query($sql);
313
						$theme_row = $db->sql_fetchrow($result);
314
						$db->sql_freeresult($result);
315
316
						if (!$theme_row)
317
						{
318
							trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
319
						}
320
321
						if (!$theme_row['theme_storedb'])
322
						{
323
							trigger_error($user->lang['THEME_ERR_REFRESH_FS'] . adm_back_link($this->u_action), E_USER_WARNING);
324
						}
325
326
						if (confirm_box(true))
327
						{
328
							if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"))
329
							{
330
								// Save CSS contents
331
								$sql_ary = array(
332
									'theme_mtime'	=> (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"),
333
									'theme_data'	=> $this->db_theme_data($theme_row)
334
								);
335
336
								$sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
337
									WHERE theme_id = $style_id";
338
								$db->sql_query($sql);
339
340
								$cache->destroy('sql', STYLES_THEME_TABLE);
341
342
								add_log('admin', 'LOG_THEME_REFRESHED', $theme_row['theme_name']);
343
								trigger_error($user->lang['THEME_REFRESHED'] . adm_back_link($this->u_action));
344
							}
345
						}
346
						else
347
						{
348
							confirm_box(false, $user->lang['CONFIRM_THEME_REFRESH'], build_hidden_fields(array(
349
								'i'			=> $id,
350
								'mode'		=> $mode,
351
								'action'	=> $action,
352
								'id'		=> $style_id
353
							)));
354
						}
355
					break;
356
				}
357
358
				$this->frontend('theme', array('edit', 'details'), array('refresh', 'export', 'delete'));
359
			break;
360
361
			case 'imageset':
362
363
				switch ($action)
364
				{
365
					case 'refresh':
366
367
						$sql = 'SELECT *
368
							FROM ' . STYLES_IMAGESET_TABLE . "
369
							WHERE imageset_id = $style_id";
370
						$result = $db->sql_query($sql);
371
						$imageset_row = $db->sql_fetchrow($result);
372
						$db->sql_freeresult($result);
373
374
						if (!$imageset_row)
375
						{
376
							trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
377
						}
378
379
						if (confirm_box(true))
380
						{
381
							$sql_ary = array();
382
383
							$imageset_definitions = array();
384
							foreach ($this->imageset_keys as $topic => $key_array)
385
							{
386
								$imageset_definitions = array_merge($imageset_definitions, $key_array);
387
							}
388
389
							$cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg");
390
391
							$db->sql_transaction('begin');
392
393
							$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
394
								WHERE imageset_id = ' . $style_id;
395
							$result = $db->sql_query($sql);
396
397
							foreach ($cfg_data_imageset as $image_name => $value)
398
							{
399
								if (strpos($value, '*') !== false)
400
								{
401
									if (substr($value, -1, 1) === '*')
402
									{
403
										list($image_filename, $image_height) = explode('*', $value);
404
										$image_width = 0;
405
									}
406
									else
407
									{
408
										list($image_filename, $image_height, $image_width) = explode('*', $value);
409
									}
410
								}
411
								else
412
								{
413
									$image_filename = $value;
414
									$image_height = $image_width = 0;
415
								}
416
417
								if (strpos($image_name, 'img_') === 0 && $image_filename)
418
								{
419
									$image_name = substr($image_name, 4);
420
									if (in_array($image_name, $imageset_definitions))
421
									{
422
										$sql_ary[] = array(
423
											'image_name'		=> (string) $image_name,
424
											'image_filename'	=> (string) $image_filename,
425
											'image_height'		=> (int) $image_height,
426
											'image_width'		=> (int) $image_width,
427
											'imageset_id'		=> (int) $style_id,
428
											'image_lang'		=> '',
429
										);
430
									}
431
								}
432
							}
433
434
							$sql = 'SELECT lang_dir
435
								FROM ' . LANG_TABLE;
436
							$result = $db->sql_query($sql);
437
438
							while ($row = $db->sql_fetchrow($result))
439
							{
440
								if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"))
441
								{
442
									$cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg");
443
									foreach ($cfg_data_imageset_data as $image_name => $value)
444
									{
445
										if (strpos($value, '*') !== false)
446
										{
447
											if (substr($value, -1, 1) === '*')
448
											{
449
												list($image_filename, $image_height) = explode('*', $value);
450
												$image_width = 0;
451
											}
452
											else
453
											{
454
												list($image_filename, $image_height, $image_width) = explode('*', $value);
455
											}
456
										}
457
										else
458
										{
459
											$image_filename = $value;
460
											$image_height = $image_width = 0;
461
										}
462
463
										if (strpos($image_name, 'img_') === 0 && $image_filename)
464
										{
465
											$image_name = substr($image_name, 4);
466
											if (in_array($image_name, $imageset_definitions))
467
											{
468
												$sql_ary[] = array(
469
													'image_name'		=> (string) $image_name,
470
													'image_filename'	=> (string) $image_filename,
471
													'image_height'		=> (int) $image_height,
472
													'image_width'		=> (int) $image_width,
473
													'imageset_id'		=> (int) $style_id,
474
													'image_lang'		=> (string) $row['lang_dir'],
475
												);
476
											}
477
										}
478
									}
479
								}
480
							}
481
							$db->sql_freeresult($result);
482
483
							$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
484
485
							$db->sql_transaction('commit');
486
487
							$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
488
489
							add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']);
490
							trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action));
491
						}
492
						else
493
						{
494
							confirm_box(false, $user->lang['CONFIRM_IMAGESET_REFRESH'], build_hidden_fields(array(
495
								'i'			=> $id,
496
								'mode'		=> $mode,
497
								'action'	=> $action,
498
								'id'		=> $style_id
499
							)));
500
						}
501
					break;
502
				}
503
504
				$this->frontend('imageset', array('edit', 'details'), array('refresh', 'export', 'delete'));
505
			break;
506
		}
507
	}
508
509
	/**
510
	* Build Frontend with supplied options
511
	*/
512
	function frontend($mode, $options, $actions)
513
	{
514
		global $user, $template, $db, $config, $phpbb_root_path, $phpEx;
515
516
		$sql_from = '';
517
		$style_count = array();
518
519
		switch ($mode)
520
		{
521
			case 'style':
522
				$sql_from = STYLES_TABLE;
523
524
				$sql = 'SELECT user_style, COUNT(user_style) AS style_count
525
					FROM ' . USERS_TABLE . '
526
					GROUP BY user_style';
527
				$result = $db->sql_query($sql);
528
529
				while ($row = $db->sql_fetchrow($result))
530
				{
531
					$style_count[$row['user_style']] = $row['style_count'];
532
				}
533
				$db->sql_freeresult($result);
534
535
			break;
536
537
			case 'template':
538
				$sql_from = STYLES_TEMPLATE_TABLE;
539
			break;
540
541
			case 'theme':
542
				$sql_from = STYLES_THEME_TABLE;
543
			break;
544
545
			case 'imageset':
546
				$sql_from = STYLES_IMAGESET_TABLE;
547
			break;
548
		}
549
550
		$l_prefix = strtoupper($mode);
551
552
		$this->page_title = 'ACP_' . $l_prefix . 'S';
553
554
		$template->assign_vars(array(
555
			'S_FRONTEND'		=> true,
556
			'S_STYLE'			=> ($mode == 'style') ? true : false,
557
558
			'L_TITLE'			=> $user->lang[$this->page_title],
559
			'L_EXPLAIN'			=> $user->lang[$this->page_title . '_EXPLAIN'],
560
			'L_NAME'			=> $user->lang[$l_prefix . '_NAME'],
561
			'L_INSTALLED'		=> $user->lang['INSTALLED_' . $l_prefix],
562
			'L_UNINSTALLED'		=> $user->lang['UNINSTALLED_' . $l_prefix],
563
			'L_NO_UNINSTALLED'	=> $user->lang['NO_UNINSTALLED_' . $l_prefix],
564
			'L_CREATE'			=> $user->lang['CREATE_' . $l_prefix],
565
566
			'U_ACTION'			=> $this->u_action,
567
			)
568
		);
569
570
		$sql = "SELECT *
571
			FROM $sql_from";
572
		$result = $db->sql_query($sql);
573
574
		$installed = array();
575
576
		$basis_options = '<option class="sep" value="">' . $user->lang['OPTIONAL_BASIS'] . '</option>';
577
		while ($row = $db->sql_fetchrow($result))
578
		{
579
			$installed[] = $row[$mode . '_name'];
580
			$basis_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
581
582
			$stylevis = ($mode == 'style' && !$row['style_active']) ? 'activate' : 'deactivate';
583
584
			$s_options = array();
585
			foreach ($options as $option)
586
			{
587
				$s_options[] = '<a href="' . $this->u_action . "&amp;action=$option&amp;id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
588
			}
589
590
			$s_actions = array();
591
			foreach ($actions as $option)
592
			{
593
				$s_actions[] = '<a href="' . $this->u_action . "&amp;action=$option&amp;id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
594
			}
595
596
			$template->assign_block_vars('installed', array(
597
				'S_DEFAULT_STYLE'		=> ($mode == 'style' && $row['style_id'] == $config['default_style']) ? true : false,
598
				'U_EDIT'				=> $this->u_action . '&amp;action=' . (($mode == 'style') ? 'details' : 'edit') . '&amp;id=' . $row[$mode . '_id'],
599
				'U_STYLE_ACT_DEACT'		=> $this->u_action . '&amp;action=' . $stylevis . '&amp;id=' . $row[$mode . '_id'],
600
				'L_STYLE_ACT_DEACT'		=> $user->lang['STYLE_' . strtoupper($stylevis)],
601
				'S_OPTIONS'				=> implode(' | ', $s_options),
602
				'S_ACTIONS'				=> implode(' | ', $s_actions),
603
				'U_PREVIEW'				=> ($mode == 'style') ? append_sid("{$phpbb_root_path}index.$phpEx", "$mode=" . $row[$mode . '_id']) : '',
604
605
				'NAME'					=> $row[$mode . '_name'],
606
				'STYLE_COUNT'			=> ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
607
				)
608
			);
609
		}
610
		$db->sql_freeresult($result);
611
612
		// Grab uninstalled items
613
		$new_ary = $cfg = array();
614
615
		$dp = @opendir("{$phpbb_root_path}styles");
616
617
		if ($dp)
618
		{
619
			while (($file = readdir($dp)) !== false)
620
			{
621
				$subpath = ($mode != 'style') ? "$mode/" : '';
622
				if ($file[0] != '.' && file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
623
				{
624
					if ($cfg = file("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
625
					{
626
						$items = parse_cfg_file('', $cfg);
627
						$name = (isset($items['name'])) ? trim($items['name']) : false;
628
629
						if ($name && !in_array($name, $installed))
630
						{
631
							$new_ary[] = array(
632
								'path'		=> $file,
633
								'name'		=> $name,
634
								'copyright'	=> $items['copyright'],
635
							);
636
						}
637
					}
638
				}
639
			}
640
			closedir($dp);
641
		}
642
643
		unset($installed);
644
645
		if (sizeof($new_ary))
646
		{
647
			foreach ($new_ary as $cfg)
648
			{
649
				$template->assign_block_vars('uninstalled', array(
650
					'NAME'			=> $cfg['name'],
651
					'COPYRIGHT'		=> $cfg['copyright'],
652
					'U_INSTALL'		=> $this->u_action . '&amp;action=install&amp;path=' . urlencode($cfg['path']))
653
				);
654
			}
655
		}
656
		unset($new_ary);
657
658
		$template->assign_vars(array(
659
			'S_BASIS_OPTIONS'		=> $basis_options)
660
		);
661
662
	}
663
664
	/**
665
	* Provides a template editor which allows saving changes to template files on the filesystem or in the database.
666
	*
667
	* @param int $template_id specifies which template set is being edited
668
	*/
669
	function edit_template($template_id)
670
	{
671
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
672
673
		$this->page_title = 'EDIT_TEMPLATE';
674
675
		$filelist = $filelist_cats = array();
676
677
		$template_data	= utf8_normalize_nfc(request_var('template_data', '', true));
678
		$template_data	= htmlspecialchars_decode($template_data);
679
		$template_file	= utf8_normalize_nfc(request_var('template_file', '', true));
680
		$text_rows		= max(5, min(999, request_var('text_rows', 20)));
681
		$save_changes	= (isset($_POST['save'])) ? true : false;
682
683
		// make sure template_file path doesn't go upwards
684
		$template_file = str_replace('..', '.', $template_file);
685
		
686
		// Retrieve some information about the template
687
		$sql = 'SELECT template_storedb, template_path, template_name
688
			FROM ' . STYLES_TEMPLATE_TABLE . "
689
			WHERE template_id = $template_id";
690
		$result = $db->sql_query($sql);
691
		$template_info = $db->sql_fetchrow($result);
692
		$db->sql_freeresult($result);
693
694
		if (!$template_info)
695
		{
696
			trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
697
		}
698
699
		// save changes to the template if the user submitted any
700
		if ($save_changes && $template_file)
701
		{
702
			// Get the filesystem location of the current file
703
			$file = "{$phpbb_root_path}styles/{$template_info['template_path']}/template/$template_file";
704
			$additional = '';
705
706
			// If the template is stored on the filesystem try to write the file else store it in the database
707
			if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && @is_writable($file))
708
			{
709
				if (!($fp = @fopen($file, 'wb')))
710
				{
711
					trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
712
				}
713
				fwrite($fp, $template_data);
714
				fclose($fp);
715
			}
716
			else
717
			{
718
				$db->sql_transaction('begin');
719
720
				// If it's not stored in the db yet, then update the template setting and store all template files in the db
721
				if (!$template_info['template_storedb'])
722
				{
723
					$sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
724
						SET template_storedb = 1
725
						WHERE template_id = ' . $template_id;
726
					$db->sql_query($sql);
727
728
					$filelist = filelist("{$phpbb_root_path}styles/{$template_info['template_path']}/template", '', 'html');
729
					$this->store_templates('insert', $template_id, $template_info['template_path'], $filelist);
730
731
					add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']);
732
					$additional .= '<br />' . $user->lang['EDIT_TEMPLATE_STORED_DB'];
733
				}
734
735
				// Update the template_data table entry for this template file
736
				$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
737
					SET template_data = '" . $db->sql_escape($template_data) . "', template_mtime = " . time() . "
738
					WHERE template_id = $template_id
739
						AND template_filename = '" . $db->sql_escape($template_file) . "'";
740
				$db->sql_query($sql);
741
742
				$db->sql_transaction('commit');
743
			}
744
745
			// destroy the cached version of the template (filename without extension)
746
			$this->clear_template_cache($template_info, array(substr($template_file, 0, -5)));
747
748
			$cache->destroy('sql', STYLES_TABLE);
749
750
			add_log('admin', 'LOG_TEMPLATE_EDIT', $template_info['template_name'], $template_file);
751
			trigger_error($user->lang['TEMPLATE_FILE_UPDATED'] . $additional . adm_back_link($this->u_action . "&amp;action=edit&amp;id=$template_id&amp;text_rows=$text_rows&amp;template_file=$template_file"));
752
		}
753
754
		// Generate a category array containing template filenames
755
		if (!$template_info['template_storedb'])
756
		{
757
			$template_path = "{$phpbb_root_path}styles/{$template_info['template_path']}/template";
758
759
			$filelist = filelist($template_path, '', 'html');
760
			$filelist[''] = array_diff($filelist[''], array('bbcode.html'));
761
762
			if ($template_file)
763
			{
764
				if (!file_exists($template_path . "/$template_file") || !($template_data = file_get_contents($template_path . "/$template_file")))
765
				{
766
					trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
767
				}
768
			}
769
		}
770
		else
771
		{
772
			$sql = 'SELECT *
773
				FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
774
				WHERE template_id = $template_id";
775
			$result = $db->sql_query($sql);
776
777
			$filelist = array('' => array());
778
			while ($row = $db->sql_fetchrow($result))
779
			{
780
				$file_info = pathinfo($row['template_filename']);
781
782
				if (($file_info['basename'] != 'bbcode') && ($file_info['extension'] == 'html'))
783
				{
784
					if (($file_info['dirname'] == '.') || empty($file_info['dirname']))
785
					{
786
						$filelist[''][] = $row['template_filename'];
787
					}
788
					else
789
					{
790
						$filelist[$file_info['dirname'] . '/'][] = $file_info['basename'];
791
					}
792
				}
793
794
				if ($row['template_filename'] == $template_file)
795
				{
796
					$template_data = $row['template_data'];
797
				}
798
			}
799
			$db->sql_freeresult($result);
800
			unset($file_info);
801
		}
802
803
		// Now create the categories
804
		$filelist_cats[''] = array();
805
		foreach ($filelist as $pathfile => $file_ary)
806
		{
807
			// Use the directory name as category name
808
			if (!empty($pathfile))
809
			{
810
				$filelist_cats[$pathfile] = array();
811
				foreach ($file_ary as $file)
812
				{
813
					$filelist_cats[$pathfile][$pathfile . $file] = $file;
814
				}
815
			}
816
			// or if it's in the main category use the word before the first underscore to group files
817
			else
818
			{
819
				$cats = array();
820
				foreach ($file_ary as $file)
821
				{
822
					$cats[] = substr($file, 0, strpos($file, '_'));
823
					$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
824
				}
825
826
				$cats = array_values(array_unique($cats));
827
828
				// we don't need any single element categories so put them into the misc '' category
829
				for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
830
				{
831
					if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
832
					{
833
						$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
834
						unset($filelist_cats[$cats[$i]]);
835
					}
836
				}
837
				unset($cats);
838
			}
839
		}
840
		unset($filelist);
841
842
		// Generate list of categorised template files
843
		$tpl_options = '';
844
		ksort($filelist_cats);
845
		foreach ($filelist_cats as $category => $tpl_ary)
846
		{
847
			ksort($tpl_ary);
848
849
			if (!empty($category))
850
			{
851
				$tpl_options .= '<option class="sep" value="">' . $category . '</option>';
852
			}
853
854
			foreach ($tpl_ary as $filename => $file)
855
			{
856
				$selected = ($template_file == $filename) ? ' selected="selected"' : '';
857
				$tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
858
			}
859
		}
860
861
		$template->assign_vars(array(
862
			'S_EDIT_TEMPLATE'	=> true,
863
			'S_HIDDEN_FIELDS'	=> build_hidden_fields(array('template_file' => $template_file)),
864
			'S_TEMPLATES'		=> $tpl_options,
865
866
			'U_ACTION'			=> $this->u_action . "&amp;action=edit&amp;id=$template_id&amp;text_rows=$text_rows",
867
			'U_BACK'			=> $this->u_action,
868
869
			'L_EDIT'			=> $user->lang['EDIT_TEMPLATE'],
870
			'L_EDIT_EXPLAIN'	=> $user->lang['EDIT_TEMPLATE_EXPLAIN'],
871
			'L_EDITOR'			=> $user->lang['TEMPLATE_EDITOR'],
872
			'L_EDITOR_HEIGHT'	=> $user->lang['TEMPLATE_EDITOR_HEIGHT'],
873
			'L_FILE'			=> $user->lang['TEMPLATE_FILE'],
874
			'L_SELECT'			=> $user->lang['SELECT_TEMPLATE'],
875
			'L_SELECTED'		=> $user->lang['SELECTED_TEMPLATE'],
876
			'L_SELECTED_FILE'	=> $user->lang['SELECTED_TEMPLATE_FILE'],
877
878
			'SELECTED_TEMPLATE'	=> $template_info['template_name'],
879
			'TEMPLATE_FILE'		=> $template_file,
880
			'TEMPLATE_DATA'		=> utf8_htmlspecialchars($template_data),
881
			'TEXT_ROWS'			=> $text_rows)
882
		);
883
	}
884
885
	/**
886
	* Allows the admin to view cached versions of template files and clear single template cache files
887
	*
888
	* @param int $template_id specifies which template's cache is shown
889
	*/
890
	function template_cache($template_id)
891
	{
892
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
893
894
		$source		= str_replace('/', '.', request_var('source', ''));
895
		$file_ary	= array_diff(request_var('delete', array('')), array(''));
896
		$submit		= isset($_POST['submit']) ? true : false;
897
898
		$sql = 'SELECT *
899
			FROM ' . STYLES_TEMPLATE_TABLE . "
900
			WHERE template_id = $template_id";
901
		$result = $db->sql_query($sql);
902
		$template_row = $db->sql_fetchrow($result);
903
		$db->sql_freeresult($result);
904
905
		if (!$template_row)
906
		{
907
			trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
908
		}
909
910
		// User wants to delete one or more files ...
911
		if ($submit && $file_ary)
912
		{
913
			$this->clear_template_cache($template_row, $file_ary);
914
			trigger_error($user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action . "&amp;action=cache&amp;id=$template_id"));
915
		}
916
917
		$cache_prefix = 'tpl_' . $template_row['template_path'];
918
919
		// Someone wants to see the cached source ... so we'll highlight it,
920
		// add line numbers and indent it appropriately. This could be nasty
921
		// on larger source files ...
922
		if ($source && file_exists("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"))
923
		{
924
			adm_page_header($user->lang['TEMPLATE_CACHE']);
925
926
			$template->set_filenames(array(
927
				'body'	=> 'viewsource.html')
928
			);
929
930
			$template->assign_vars(array(
931
				'FILENAME'	=> str_replace('.', '/', $source) . '.html')
932
			);
933
934
			$code = str_replace(array("\r\n", "\r"), array("\n", "\n"), file_get_contents("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"));
935
936
			$conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
937
			foreach ($conf as $ini_var)
938
			{
939
				@ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
940
			}
941
942
			$marker = 'MARKER' . time();
943
			$code = highlight_string(str_replace("\n", $marker, $code), true);
944
			$code = str_replace($marker, "\n", $code);
945
			$str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
946
			$str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '&#91;', '&#93;', '&#46;', '&#58;');
947
948
			$code = str_replace($str_from, $str_to, $code);
949
			$code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#ism', '$1$2$3', $code);
950
			$code = substr($code, strlen('<span class="syntaxhtml">'));
951
			$code = substr($code, 0, -1 * strlen('</ span>'));
952
			$code = explode("\n", $code);
953
954
			foreach ($code as $key => $line)
955
			{
956
				$template->assign_block_vars('source', array(
957
					'LINENUM'	=> $key + 1,
958
					'LINE'		=> preg_replace('#([^ ;])&nbsp;([^ &])#', '$1 $2', $line))
959
				);
960
				unset($code[$key]);
961
			}
962
963
			adm_page_footer();
964
		}
965
966
		$filemtime = array();
967
		if ($template_row['template_storedb'])
968
		{
969
			$sql = 'SELECT template_filename, template_mtime
970
				FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
971
				WHERE template_id = $template_id";
972
			$result = $db->sql_query($sql);
973
974
			$filemtime = array();
975
			while ($row = $db->sql_fetchrow($result))
976
			{
977
				$filemtime[$row['template_filename']] = $row['template_mtime'];
978
			}
979
			$db->sql_freeresult($result);
980
		}
981
982
		// Get a list of cached template files and then retrieve additional information about them
983
		$file_ary = $this->template_cache_filelist($template_row['template_path']);
984
985
		foreach ($file_ary as $file)
986
		{
987
			$file 		= str_replace('/', '.', $file);
988
			
989
			// perform some dirty guessing to get the path right.
990
			// We assume that three dots in a row were '../'
991
			$tpl_file 	= str_replace('.', '/', $file);
992
			$tpl_file 	= str_replace('///', '../', $tpl_file);
993
			
994
			$filename = "{$cache_prefix}_$file.html.$phpEx";
995
996
			if (!file_exists("{$phpbb_root_path}cache/$filename"))
997
			{
998
				continue;
999
			}
1000
1001
			$template->assign_block_vars('file', array(
1002
				'U_VIEWSOURCE'	=> $this->u_action . "&amp;action=cache&amp;id=$template_id&amp;source=$file",
1003
1004
				'CACHED'		=> $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")),
1005
				'FILENAME'		=> $file,
1006
				'FILESIZE'		=> sprintf('%.1f KB', filesize("{$phpbb_root_path}cache/$filename") / 1024),
1007
				'MODIFIED'		=> $user->format_date((!$template_row['template_storedb']) ? filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html") : $filemtime[$file . '.html']))
1008
			);
1009
		}
1010
		unset($filemtime);
1011
1012
		$template->assign_vars(array(
1013
			'S_CACHE'			=> true,
1014
			'S_TEMPLATE'		=> true,
1015
1016
			'U_ACTION'			=> $this->u_action . "&amp;action=cache&amp;id=$template_id",
1017
			'U_BACK'			=> $this->u_action)
1018
		);
1019
	}
1020
1021
	/**
1022
	* Provides a css editor and a basic easier to use stylesheet editing tool for less experienced (or lazy) users
1023
	*
1024
	* @param int $theme_id specifies which theme is being edited
1025
	*/
1026
	function edit_theme($theme_id)
1027
	{
1028
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
1029
1030
		$this->page_title = 'EDIT_THEME';
1031
1032
		$filelist = $filelist_cats = array();
1033
1034
		$theme_data		= utf8_normalize_nfc(request_var('template_data', '', true));
1035
		$theme_data		= htmlspecialchars_decode($theme_data);
1036
		$theme_file		= utf8_normalize_nfc(request_var('template_file', '', true));
1037
		$text_rows		= max(5, min(999, request_var('text_rows', 20)));
1038
		$save_changes	= (isset($_POST['save'])) ? true : false;
1039
1040
		// make sure theme_file path doesn't go upwards
1041
		$theme_file = str_replace('..', '.', $theme_file);
1042
		
1043
		// Retrieve some information about the theme
1044
		$sql = 'SELECT theme_storedb, theme_path, theme_name, theme_data
1045
			FROM ' . STYLES_THEME_TABLE . "
1046
			WHERE theme_id = $theme_id";
1047
		$result = $db->sql_query($sql);
1048
1049
		if (!($theme_info = $db->sql_fetchrow($result)))
1050
		{
1051
			trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1052
		}
1053
		$db->sql_freeresult($result);
1054
1055
		// save changes to the theme if the user submitted any
1056
		if ($save_changes)
1057
		{
1058
			// Get the filesystem location of the current file
1059
			$file = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/$theme_file";
1060
			$additional = '';
1061
			$message = $user->lang['THEME_UPDATED'];
1062
1063
			// If the theme is stored on the filesystem try to write the file else store it in the database
1064
			if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && @is_writable($file))
1065
			{
1066
				if (!($fp = @fopen($file, 'wb')))
1067
				{
1068
					trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1069
				}
1070
				fwrite($fp, $theme_data);
1071
				fclose($fp);
1072
			}
1073
			else
1074
			{
1075
				// Write stylesheet to db
1076
				$sql_ary = array(
1077
					'theme_mtime'		=> time(),
1078
					'theme_storedb'		=> 1,
1079
					'theme_data'		=> $this->db_theme_data($theme_info, $theme_data),
1080
				);
1081
				$sql = 'UPDATE ' . STYLES_THEME_TABLE . '
1082
					SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1083
					WHERE theme_id = ' . $theme_id;
1084
				$db->sql_query($sql);
1085
1086
				$cache->destroy('sql', STYLES_THEME_TABLE);
1087
1088
				// notify the user if the theme was not stored in the db before his modification
1089
				if (!$theme_info['theme_storedb'])
1090
				{
1091
					add_log('admin', 'LOG_THEME_EDIT_DETAILS', $theme_info['theme_name']);
1092
					$message .= '<br />' . $user->lang['EDIT_THEME_STORED_DB'];
1093
				}
1094
			}
1095
			$cache->destroy('sql', STYLES_THEME_TABLE);
1096
			add_log('admin', (!$theme_info['theme_storedb']) ? 'LOG_THEME_EDIT_FILE' : 'LOG_THEME_EDIT', $theme_info['theme_name'], (!$theme_info['theme_storedb']) ? $theme_file : '');
1097
1098
			trigger_error($message . adm_back_link($this->u_action . "&amp;action=edit&amp;id=$theme_id&amp;template_file=$theme_file&amp;text_rows=$text_rows"));
1099
		}
1100
1101
		// Generate a category array containing theme filenames
1102
		if (!$theme_info['theme_storedb'])
1103
		{
1104
			$theme_path = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme";
1105
1106
			$filelist = filelist($theme_path, '', 'css');
1107
1108
			if ($theme_file)
1109
			{
1110
				if (!file_exists($theme_path . "/$theme_file") || !($theme_data = file_get_contents($theme_path . "/$theme_file")))
1111
				{
1112
					trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1113
				}
1114
			}
1115
		}
1116
		else
1117
		{
1118
			$theme_data = &$theme_info['theme_data'];
1119
		}
1120
1121
		// Now create the categories
1122
		$filelist_cats[''] = array();
1123
		foreach ($filelist as $pathfile => $file_ary)
1124
		{
1125
			// Use the directory name as category name
1126
			if (!empty($pathfile))
1127
			{
1128
				$filelist_cats[$pathfile] = array();
1129
				foreach ($file_ary as $file)
1130
				{
1131
					$filelist_cats[$pathfile][$pathfile . $file] = $file;
1132
				}
1133
			}
1134
			// or if it's in the main category use the word before the first underscore to group files
1135
			else
1136
			{
1137
				$cats = array();
1138
				foreach ($file_ary as $file)
1139
				{
1140
					$cats[] = substr($file, 0, strpos($file, '_'));
1141
					$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
1142
				}
1143
1144
				$cats = array_values(array_unique($cats));
1145
1146
				// we don't need any single element categories so put them into the misc '' category
1147
				for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
1148
				{
1149
					if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
1150
					{
1151
						$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
1152
						unset($filelist_cats[$cats[$i]]);
1153
					}
1154
				}
1155
				unset($cats);
1156
			}
1157
		}
1158
		unset($filelist);
1159
1160
		// Generate list of categorised theme files
1161
		$tpl_options = '';
1162
		ksort($filelist_cats);
1163
		foreach ($filelist_cats as $category => $tpl_ary)
1164
		{
1165
			ksort($tpl_ary);
1166
1167
			if (!empty($category))
1168
			{
1169
				$tpl_options .= '<option class="sep" value="">' . $category . '</option>';
1170
			}
1171
1172
			foreach ($tpl_ary as $filename => $file)
1173
			{
1174
				$selected = ($theme_file == $filename) ? ' selected="selected"' : '';
1175
				$tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
1176
			}
1177
		}
1178
1179
		$template->assign_vars(array(
1180
			'S_EDIT_THEME'		=> true,
1181
			'S_HIDDEN_FIELDS'	=> build_hidden_fields(array('template_file' => $theme_file)),
1182
			'S_THEME_IN_DB'		=> $theme_info['theme_storedb'],
1183
			'S_TEMPLATES'		=> $tpl_options,
1184
1185
			'U_ACTION'			=> $this->u_action . "&amp;action=edit&amp;id=$theme_id&amp;text_rows=$text_rows",
1186
			'U_BACK'			=> $this->u_action,
1187
1188
			'L_EDIT'			=> $user->lang['EDIT_THEME'],
1189
			'L_EDIT_EXPLAIN'	=> $user->lang['EDIT_THEME_EXPLAIN'],
1190
			'L_EDITOR'			=> $user->lang['THEME_EDITOR'],
1191
			'L_EDITOR_HEIGHT'	=> $user->lang['THEME_EDITOR_HEIGHT'],
1192
			'L_FILE'			=> $user->lang['THEME_FILE'],
1193
			'L_SELECT'			=> $user->lang['SELECT_THEME'],
1194
			'L_SELECTED'		=> $user->lang['SELECTED_THEME'],
1195
			'L_SELECTED_FILE'	=> $user->lang['SELECTED_THEME_FILE'],
1196
1197
			'SELECTED_TEMPLATE'	=> $theme_info['theme_name'],
1198
			'TEMPLATE_FILE'		=> $theme_file,
1199
			'TEMPLATE_DATA'		=> utf8_htmlspecialchars($theme_data),
1200
			'TEXT_ROWS'			=> $text_rows)
1201
		);
1202
	}
1203
1204
1205
	/**
1206
	* Edit imagesets
1207
	*
1208
	* @param int $imageset_id specifies which imageset is being edited
1209
	*/
1210
	function edit_imageset($imageset_id)
1211
	{
1212
		global $db, $user, $phpbb_root_path, $cache, $template;
1213
1214
		$this->page_title = 'EDIT_IMAGESET';
1215
1216
		$update		= (isset($_POST['update'])) ? true : false;
1217
1218
		$imgname	= request_var('imgname', '');
1219
		$imgpath	= request_var('imgpath', '');
1220
		$imgsize	= request_var('imgsize', false);
1221
		$imgwidth	= request_var('imgwidth', 0);
1222
		$imgheight	= request_var('imgheight', 0);
1223
		
1224
		$imgname	= preg_replace('#[^a-z0-9\-+_]#i', '', $imgname);
1225
		$imgpath	= str_replace('..', '.', $imgpath);
1226
1227
		if ($imageset_id)
1228
		{
1229
			$sql = 'SELECT imageset_path, imageset_name
1230
				FROM ' . STYLES_IMAGESET_TABLE . "
1231
				WHERE imageset_id = $imageset_id";
1232
			$result = $db->sql_query($sql);
1233
			$imageset_row = $db->sql_fetchrow($result);
1234
			$db->sql_freeresult($result);
1235
1236
			$imageset_path		= $imageset_row['imageset_path'];
1237
			$imageset_name		= $imageset_row['imageset_name'];
1238
1239
			$sql_extra = '';
1240
			if (strpos($imgname, '-') !== false)
1241
			{
1242
				list($imgname, $imgnamelang) = explode('-', $imgname);
1243
				$sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')";
1244
			}
1245
1246
			$sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id
1247
				FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1248
				WHERE imageset_id = $imageset_id
1249
					AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra";
1250
			$result = $db->sql_query($sql);
1251
			$imageset_data_row = $db->sql_fetchrow($result);
1252
			$db->sql_freeresult($result);
1253
1254
			$image_filename	= $imageset_data_row['image_filename'];
1255
			$image_width	= $imageset_data_row['image_width'];
1256
			$image_height	= $imageset_data_row['image_height'];
1257
			$image_lang		= $imageset_data_row['image_lang'];
1258
			$image_id		= $imageset_data_row['image_id'];
1259
1260
			if (!$imageset_row)
1261
			{
1262
				trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
1263
			}
1264
1265
			// Check to see whether the selected image exists in the table
1266
			$valid_name = ($update) ? false : true;
1267
1268
			foreach ($this->imageset_keys as $category => $img_ary)
1269
			{
1270
				if (in_array($imgname, $img_ary))
1271
				{
1272
					$valid_name = true;
1273
					break;
1274
				}
1275
			}
1276
1277
			if ($update && isset($_POST['imgpath']))
1278
			{
1279
				if ($valid_name)
1280
				{
1281
					// If imgwidth and imgheight are non-zero grab the actual size
1282
					// from the image itself ... we ignore width settings for the poll center image
1283
					$imgwidth	= request_var('imgwidth', 0);
1284
					$imgheight	= request_var('imgheight', 0);
1285
					$imglang = '';
1286
1287
					if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"))
1288
					{
1289
						trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
1290
					}
1291
1292
					if ($imgsize && $imgpath)
1293
					{
1294
						if (!$imgwidth || !$imgheight)
1295
						{
1296
							list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath");
1297
							$imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file;
1298
							$imgheight = ($imgheight) ? $imgheight : $imgheight_file;
1299
						}
1300
						$imgwidth	= ($imgname != 'poll_center') ? (int) $imgwidth : 0;
1301
						$imgheight	= (int) $imgheight;
1302
					}
1303
1304
1305
					if (strpos($imgpath, '/') !== false)
1306
					{
1307
						list($imglang, $imgfilename) = explode('/', $imgpath);
1308
					}
1309
					else
1310
					{
1311
						$imgfilename = $imgpath;
1312
					}
1313
1314
					$sql_ary = array(
1315
						'image_filename'	=> (string) $imgfilename,
1316
						'image_width'		=> (int) $imgwidth,
1317
						'image_height'		=> (int) $imgheight,
1318
						'image_lang'		=> (string) $imglang,
1319
					);
1320
1321
					// already exists
1322
					if ($imageset_data_row)
1323
					{
1324
						$sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . '
1325
							SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
1326
							WHERE image_id = $image_id";
1327
						$db->sql_query($sql);
1328
					}
1329
					// does not exist
1330
					else if (!$imageset_data_row)
1331
					{
1332
						$sql_ary['image_name']	= $imgname;
1333
						$sql_ary['imageset_id']	= (int) $imageset_id;
1334
						$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1335
					}
1336
1337
					$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
1338
1339
					add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name);
1340
1341
					$template->assign_var('SUCCESS', true);
1342
1343
					$image_filename = $imgfilename;
1344
					$image_width	= $imgwidth;
1345
					$image_height	= $imgheight;
1346
					$image_lang		= $imglang;
1347
				}
1348
			}
1349
		}
1350
1351
		$imglang = '';
1352
		$imagesetlist = array('nolang' => array(), 'lang' => array());
1353
		$langs = array();
1354
1355
		$dir = "{$phpbb_root_path}styles/$imageset_path/imageset";
1356
		$dp = @opendir($dir);
1357
1358
		if ($dp)
1359
		{
1360
			while (($file = readdir($dp)) !== false)
1361
			{
1362
				if ($file[0] != '.' && strtoupper($file) != 'CVS' && !is_file($dir . '/' . $file) && !is_link($dir . '/' . $file))
1363
				{
1364
					$langs[] = $file;
1365
				}
1366
				else if (preg_match('#\.(?:gif|jpg|png)$#', $file))
1367
				{
1368
					$imagesetlist['nolang'][] = $file;
1369
				}
1370
			}
1371
1372
			if ($sql_extra)
1373
			{
1374
				$dp2 = @opendir("$dir/$imgnamelang");
1375
1376
				if ($dp2)
1377
				{
1378
					while (($file2 = readdir($dp2)) !== false)
1379
					{
1380
						if (preg_match('#\.(?:gif|jpg|png)$#', $file2))
1381
						{
1382
							$imagesetlist['lang'][] = "$imgnamelang/$file2";
1383
						}
1384
					}
1385
					closedir($dp2);
1386
				}
1387
			}
1388
			closedir($dp);
1389
		}
1390
1391
		// Generate list of image options
1392
		$img_options = '';
1393
		foreach ($this->imageset_keys as $category => $img_ary)
1394
		{
1395
			$template->assign_block_vars('category', array(
1396
				'NAME'			=> $user->lang['IMG_CAT_' . strtoupper($category)]
1397
			));
1398
1399
			foreach ($img_ary as $img)
1400
			{
1401
				if ($category == 'buttons')
1402
				{
1403
					foreach ($langs as $language)
1404
					{
1405
						$template->assign_block_vars('category.images', array(
1406
							'SELECTED'			=> ($img == $imgname && $language == $imgnamelang),
1407
							'VALUE'				=> $img . '-' . $language,
1408
							'TEXT'				=> $user->lang['IMG_' . strtoupper($img)] . ' [ ' . $language . ' ]'
1409
						));
1410
					}
1411
				}
1412
				else
1413
				{
1414
					$template->assign_block_vars('category.images', array(
1415
						'SELECTED'			=> ($img == $imgname),
1416
						'VALUE'				=> $img,
1417
						'TEXT'				=> (($category == 'custom') ? $img : $user->lang['IMG_' . strtoupper($img)])
1418
					));
1419
				}
1420
			}
1421
		}
1422
1423
		// Make sure the list of possible images is sorted alphabetically
1424
		sort($imagesetlist['lang']);
1425
		sort($imagesetlist['nolang']);
1426
1427
		$image_found = false;
1428
		$img_val = '';
1429
		foreach ($imagesetlist as $type => $img_ary)
1430
		{
1431
			if ($type !== 'lang' || $sql_extra)
1432
			{
1433
				$template->assign_block_vars('imagesetlist', array(
1434
					'TYPE'	=> ($type == 'lang')
1435
				));
1436
			}
1437
1438
			foreach ($img_ary as $img)
1439
			{
1440
				$imgtext = preg_replace('/^([^\/]+\/)/', '', $img);
1441
				$selected = (!empty($imgname) && strpos($image_filename, $imgtext) !== false);
1442
				if ($selected)
1443
				{
1444
					$image_found = true;
1445
					$img_val = htmlspecialchars($img);
1446
				}
1447
				$template->assign_block_vars('imagesetlist.images', array(
1448
					'SELECTED'			=> $selected,
1449
					'TEXT'				=> $imgtext,
1450
					'VALUE'				=> htmlspecialchars($img)
1451
				));
1452
			}
1453
		}
1454
1455
		$imgsize_bool = (!empty($imgname) && $image_width && $image_height) ? true : false;
1456
		$image_request = '../styles/' . $imageset_path . '/imageset/' . ($image_lang ? $imgnamelang . '/' : '') . $image_filename;
1457
1458
		$template->assign_vars(array(
1459
			'S_EDIT_IMAGESET'	=> true,
1460
			'L_TITLE'			=> $user->lang[$this->page_title],
1461
			'L_EXPLAIN'			=> $user->lang[$this->page_title . '_EXPLAIN'],
1462
			'IMAGE_OPTIONS'		=> $img_options,
1463
			'IMAGE_SIZE'		=> $image_width,
1464
			'IMAGE_HEIGHT'		=> $image_height,
1465
			'IMAGE_REQUEST'		=> (empty($image_filename)) ? 'images/no_image.png' : $image_request,
1466
			'U_ACTION'			=> $this->u_action . "&amp;action=edit&amp;id=$imageset_id",
1467
			'U_BACK'			=> $this->u_action,
1468
			'NAME'				=> $imageset_name,
1469
			'A_NAME'			=> addslashes($imageset_name),
1470
			'ERROR'				=> !$valid_name,
1471
			'IMG_SRC'			=> ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png',
1472
			'IMAGE_SELECT'		=> $image_found
1473
		));
1474
	}
1475
1476
	/**
1477
	* Remove style/template/theme/imageset
1478
	*/
1479
	function remove($mode, $style_id)
1480
	{
1481
		global $db, $template, $user, $phpbb_root_path, $cache, $config;
1482
1483
		$new_id = request_var('new_id', 0);
1484
		$update = (isset($_POST['update'])) ? true : false;
1485
		$sql_where = '';
1486
1487
		switch ($mode)
1488
		{
1489
			case 'style':
1490
				$sql_from = STYLES_TABLE;
1491
				$sql_select = 'style_name';
1492
				$sql_where = 'AND style_active = 1';
1493
			break;
1494
1495
			case 'template':
1496
				$sql_from = STYLES_TEMPLATE_TABLE;
1497
				$sql_select = 'template_name, template_path, template_storedb';
1498
			break;
1499
1500
			case 'theme':
1501
				$sql_from = STYLES_THEME_TABLE;
1502
				$sql_select = 'theme_name, theme_path, theme_storedb';
1503
			break;
1504
1505
			case 'imageset':
1506
				$sql_from = STYLES_IMAGESET_TABLE;
1507
				$sql_select = 'imageset_name, imageset_path';
1508
			break;
1509
		}
1510
1511
		$l_prefix = strtoupper($mode);
1512
1513
		$sql = "SELECT $sql_select
1514
			FROM $sql_from
1515
			WHERE {$mode}_id = $style_id";
1516
		$result = $db->sql_query($sql);
1517
		$style_row = $db->sql_fetchrow($result);
1518
		$db->sql_freeresult($result);
1519
1520
		if (!$style_row)
1521
		{
1522
			trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1523
		}
1524
1525
		$sql = "SELECT {$mode}_id, {$mode}_name
1526
			FROM $sql_from
1527
			WHERE {$mode}_id <> $style_id
1528
			$sql_where
1529
			ORDER BY {$mode}_name ASC";
1530
		$result = $db->sql_query($sql);
1531
1532
		$s_options = '';
1533
1534
		if ($row = $db->sql_fetchrow($result))
1535
		{
1536
			do
1537
			{
1538
				$s_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
1539
			}
1540
			while ($row = $db->sql_fetchrow($result));
1541
		}
1542
		else
1543
		{
1544
			trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1545
		}
1546
		$db->sql_freeresult($result);
1547
1548
		if ($update)
1549
		{
1550
			$sql = "DELETE FROM $sql_from
1551
				WHERE {$mode}_id = $style_id";
1552
			$db->sql_query($sql);
1553
1554
			if ($mode == 'style')
1555
			{
1556
				$sql = 'UPDATE ' . USERS_TABLE . "
1557
					SET user_style = $new_id
1558
					WHERE user_style = $style_id";
1559
				$db->sql_query($sql);
1560
1561
				$sql = 'UPDATE ' . FORUMS_TABLE . "
1562
					SET forum_style = $new_id
1563
					WHERE forum_style = $style_id";
1564
				$db->sql_query($sql);
1565
1566
				if ($style_id == $config['default_style'])
1567
				{
1568
					set_config('default_style', $new_id);
1569
				}
1570
			}
1571
			else
1572
			{
1573
				if ($mode == 'imageset')
1574
				{
1575
					$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1576
						WHERE imageset_id = $style_id";
1577
					$db->sql_query($sql);
1578
				}
1579
				$sql = 'UPDATE ' . STYLES_TABLE . "
1580
					SET {$mode}_id = $new_id
1581
					WHERE {$mode}_id = $style_id";
1582
				$db->sql_query($sql);
1583
			}
1584
1585
			$cache->destroy('sql', STYLES_TABLE);
1586
1587
			add_log('admin', 'LOG_' . $l_prefix . '_DELETE', $style_row[$mode . '_name']);
1588
			$message = ($mode != 'style') ? $l_prefix . '_DELETED_FS' : $l_prefix . '_DELETED';
1589
			trigger_error($user->lang[$message] . adm_back_link($this->u_action));
1590
		}
1591
1592
		$this->page_title = 'DELETE_' . $l_prefix;
1593
1594
		$template->assign_vars(array(
1595
			'S_DELETE'			=> true,
1596
			'S_REPLACE_OPTIONS'	=> $s_options,
1597
1598
			'L_TITLE'			=> $user->lang[$this->page_title],
1599
			'L_EXPLAIN'			=> $user->lang[$this->page_title . '_EXPLAIN'],
1600
			'L_NAME'			=> $user->lang[$l_prefix . '_NAME'],
1601
			'L_REPLACE'			=> $user->lang['REPLACE_' . $l_prefix],
1602
			'L_REPLACE_EXPLAIN'	=> $user->lang['REPLACE_' . $l_prefix . '_EXPLAIN'],
1603
1604
			'U_ACTION'		=> $this->u_action . "&amp;action=delete&amp;id=$style_id",
1605
			'U_BACK'		=> $this->u_action,
1606
1607
			'NAME'			=> $style_row[$mode . '_name'],
1608
			)
1609
		);
1610
	}
1611
1612
	/**
1613
	* Export style or style elements
1614
	*/
1615
	function export($mode, $style_id)
1616
	{
1617
		global $db, $template, $user, $phpbb_root_path, $cache, $phpEx, $config;
1618
1619
		$update = (isset($_POST['update'])) ? true : false;
1620
1621
		$inc_template = request_var('inc_template', 0);
1622
		$inc_theme = request_var('inc_theme', 0);
1623
		$inc_imageset = request_var('inc_imageset', 0);
1624
		$store = request_var('store', 0);
1625
		$format = request_var('format', '');
1626
1627
		$error = array();
1628
		$methods = array('tar');
1629
1630
		$available_methods = array('tar.gz' => 'zlib', 'tar.bz2' => 'bz2', 'zip' => 'zlib');
1631
		foreach ($available_methods as $type => $module)
1632
		{
1633
			if (!@extension_loaded($module))
1634
			{
1635
				continue;
1636
			}
1637
1638
			$methods[] = $type;
1639
		}
1640
1641
		if (!in_array($format, $methods))
1642
		{
1643
			$format = 'tar';
1644
		}
1645
1646
		switch ($mode)
1647
		{
1648
			case 'style':
1649
				if ($update && ($inc_template + $inc_theme + $inc_imageset) < 1)
1650
				{
1651
					$error[] = $user->lang['STYLE_ERR_MORE_ELEMENTS'];
1652
				}
1653
1654
				$name = 'style_name';
1655
1656
				$sql_select = 's.style_id, s.style_name, s.style_copyright';
1657
				$sql_select .= ($inc_template) ? ', t.*' : ', t.template_name';
1658
				$sql_select .= ($inc_theme) ? ', c.*' : ', c.theme_name';
1659
				$sql_select .= ($inc_imageset) ? ', i.*' : ', i.imageset_name';
1660
				$sql_from = STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . ' i';
1661
				$sql_where = "s.style_id = $style_id AND t.template_id = s.template_id AND c.theme_id = s.theme_id AND i.imageset_id = s.imageset_id";
1662
1663
				$l_prefix = 'STYLE';
1664
			break;
1665
1666
			case 'template':
1667
				$name = 'template_name';
1668
1669
				$sql_select = '*';
1670
				$sql_from = STYLES_TEMPLATE_TABLE;
1671
				$sql_where = "template_id = $style_id";
1672
1673
				$l_prefix = 'TEMPLATE';
1674
			break;
1675
1676
			case 'theme':
1677
				$name = 'theme_name';
1678
1679
				$sql_select = '*';
1680
				$sql_from = STYLES_THEME_TABLE;
1681
				$sql_where = "theme_id = $style_id";
1682
1683
				$l_prefix = 'THEME';
1684
			break;
1685
1686
			case 'imageset':
1687
				$name = 'imageset_name';
1688
1689
				$sql_select = '*';
1690
				$sql_from = STYLES_IMAGESET_TABLE;
1691
				$sql_where = "imageset_id = $style_id";
1692
1693
				$l_prefix = 'IMAGESET';
1694
			break;
1695
		}
1696
1697
		if ($update && !sizeof($error))
1698
		{
1699
			$sql = "SELECT $sql_select
1700
				FROM $sql_from
1701
				WHERE $sql_where";
1702
			$result = $db->sql_query($sql);
1703
			$style_row = $db->sql_fetchrow($result);
1704
			$db->sql_freeresult($result);
1705
1706
			if (!$style_row)
1707
			{
1708
				trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1709
			}
1710
1711
			$var_ary = array('style_id', 'style_name', 'style_copyright', 'template_id', 'template_name', 'template_path', 'template_copyright', 'template_storedb', 'bbcode_bitfield', 'theme_id', 'theme_name', 'theme_path', 'theme_copyright', 'theme_storedb', 'theme_mtime', 'theme_data', 'imageset_id', 'imageset_name', 'imageset_path', 'imageset_copyright');
1712
1713
			foreach ($var_ary as $var)
1714
			{
1715
				if (!isset($style_row[$var]))
1716
				{
1717
					$style_row[$var] = '';
1718
				}
1719
			}
1720
1721
			$files = $data = array();
1722
1723
			if ($mode == 'style')
1724
			{
1725
				$style_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['style_name'], $style_row['style_copyright'], $config['version']), $this->style_cfg);
1726
1727
				$style_cfg .= (!$inc_template) ? "\nrequired_template = {$style_row['template_name']}" : '';
1728
				$style_cfg .= (!$inc_theme) ? "\nrequired_theme = {$style_row['theme_name']}" : '';
1729
				$style_cfg .= (!$inc_imageset) ? "\nrequired_imageset = {$style_row['imageset_name']}" : '';
1730
1731
				$data[] = array(
1732
					'src'		=> $style_cfg,
1733
					'prefix'	=> 'style.cfg'
1734
				);
1735
1736
				unset($style_cfg);
1737
			}
1738
1739
			// Export template core code
1740
			if ($mode == 'template' || $inc_template)
1741
			{
1742
				$template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version']), $this->template_cfg);
1743
				$template_cfg .= "\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";
1744
1745
				$data[] = array(
1746
					'src'		=> $template_cfg,
1747
					'prefix'	=> 'template/template.cfg'
1748
				);
1749
1750
				// This is potentially nasty memory-wise ...
1751
				if (!$style_row['template_storedb'])
1752
				{
1753
					$files[] = array(
1754
						'src'		=> "styles/{$style_row['template_path']}/template/",
1755
						'prefix-'	=> "styles/{$style_row['template_path']}/",
1756
						'prefix+'	=> false,
1757
						'exclude'	=> 'template.cfg'
1758
					);
1759
				}
1760
				else
1761
				{
1762
					$sql = 'SELECT template_filename, template_data
1763
						FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
1764
						WHERE template_id = {$style_row['template_id']}";
1765
					$result = $db->sql_query($sql);
1766
1767
					while ($row = $db->sql_fetchrow($result))
1768
					{
1769
						$data[] = array(
1770
							'src' => $row['template_data'],
1771
							'prefix' => 'template/' . $row['template_filename']
1772
						);
1773
					}
1774
					$db->sql_freeresult($result);
1775
				}
1776
				unset($template_cfg);
1777
			}
1778
1779
			// Export theme core code
1780
			if ($mode == 'theme' || $inc_theme)
1781
			{
1782
				$theme_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['theme_name'], $style_row['theme_copyright'], $config['version']), $this->theme_cfg);
1783
1784
				// Read old cfg file
1785
				$items = $cache->obtain_cfg_items($style_row);
1786
				$items = $items['theme'];
1787
1788
				if (!isset($items['parse_css_file']))
1789
				{
1790
					$items['parse_css_file'] = 'off';
1791
				}
1792
1793
				$theme_cfg = str_replace(array('{PARSE_CSS_FILE}'), array($items['parse_css_file']), $theme_cfg);
1794
1795
				$files[] = array(
1796
					'src'		=> "styles/{$style_row['theme_path']}/theme/",
1797
					'prefix-'	=> "styles/{$style_row['theme_path']}/",
1798
					'prefix+'	=> false,
1799
					'exclude'	=> ($style_row['theme_storedb']) ? 'stylesheet.css,theme.cfg' : 'theme.cfg'
1800
				);
1801
1802
				$data[] = array(
1803
					'src'		=> $theme_cfg,
1804
					'prefix'	=> 'theme/theme.cfg'
1805
				);
1806
1807
				if ($style_row['theme_storedb'])
1808
				{
1809
					$data[] = array(
1810
						'src'		=> $style_row['theme_data'],
1811
						'prefix'	=> 'theme/stylesheet.css'
1812
					);
1813
				}
1814
1815
				unset($items, $theme_cfg);
1816
			}
1817
1818
			// Export imageset core code
1819
			if ($mode == 'imageset' || $inc_imageset)
1820
			{
1821
				$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
1822
1823
				$imageset_main = array();
1824
1825
				$sql = 'SELECT image_filename, image_name, image_height, image_width
1826
					FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1827
					WHERE imageset_id = $style_id
1828
						AND image_lang = ''";
1829
				$result = $db->sql_query($sql);
1830
				while ($row = $db->sql_fetchrow($result))
1831
				{
1832
					$imageset_main[$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
1833
				}
1834
				$db->sql_freeresult($result);
1835
1836
				foreach ($this->imageset_keys as $topic => $key_array)
1837
				{
1838
					foreach ($key_array as $key)
1839
					{
1840
						if (isset($imageset_main[$key]))
1841
						{
1842
							$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_main[$key]);
1843
						}
1844
					}
1845
				}
1846
1847
				$files[] = array(
1848
					'src'		=> "styles/{$style_row['imageset_path']}/imageset/",
1849
					'prefix-'	=> "styles/{$style_row['imageset_path']}/",
1850
					'prefix+'	=> false,
1851
					'exclude'	=> 'imageset.cfg'
1852
				);
1853
1854
				$data[] = array(
1855
					'src'		=> trim($imageset_cfg),
1856
					'prefix'	=> 'imageset/imageset.cfg'
1857
				);
1858
1859
				end($data);
1860
1861
				$imageset_root = "{$phpbb_root_path}styles/{$style_row['imageset_path']}/imageset/";
1862
1863
				if ($dh = @opendir($imageset_root))
1864
				{
1865
					while (($fname = readdir($dh)) !== false)
1866
					{
1867
						if ($fname[0] != '.' && $fname != 'CVS' && is_dir("$imageset_root$fname"))
1868
						{
1869
							$files[key($files)]['exclude'] .= ',' . $fname . '/imageset.cfg';
1870
						}
1871
					}
1872
					closedir($dh);
1873
				}
1874
1875
				$imageset_lang = array();
1876
1877
				$sql = 'SELECT image_filename, image_name, image_height, image_width, image_lang
1878
					FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1879
					WHERE imageset_id = $style_id
1880
						AND image_lang <> ''";
1881
				$result = $db->sql_query($sql);
1882
				while ($row = $db->sql_fetchrow($result))
1883
				{
1884
					$imageset_lang[$row['image_lang']][$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
1885
				}
1886
				$db->sql_freeresult($result);
1887
1888
				foreach ($imageset_lang as $lang => $imageset_localized)
1889
				{
1890
					$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
1891
1892
					foreach ($this->imageset_keys as $topic => $key_array)
1893
					{
1894
						foreach ($key_array as $key)
1895
						{
1896
							if (isset($imageset_localized[$key]))
1897
							{
1898
								$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_localized[$key]);
1899
							}
1900
						}
1901
					}
1902
1903
					$data[] = array(
1904
						'src'		=> trim($imageset_cfg),
1905
						'prefix'	=> 'imageset/' . $lang . '/imageset.cfg'
1906
					);
1907
				}
1908
1909
				unset($imageset_cfg);
1910
			}
1911
1912
			switch ($format)
1913
			{
1914
				case 'tar':
1915
					$ext = '.tar';
1916
					$mimetype = 'x-tar';
1917
					$compress = 'compress_tar';
1918
				break;
1919
1920
				case 'zip':
1921
					$ext = '.zip';
1922
					$mimetype = 'zip';
1923
				break;
1924
1925
				case 'tar.gz':
1926
					$ext = '.tar.gz';
1927
					$mimetype = 'x-gzip';
1928
				break;
1929
1930
				case 'tar.bz2':
1931
					$ext = '.tar.bz2';
1932
					$mimetype = 'x-bzip2';
1933
				break;
1934
1935
				default:
1936
					$error[] = $user->lang[$l_prefix . '_ERR_ARCHIVE'];
1937
			}
1938
1939
			if (!sizeof($error))
1940
			{
1941
				include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
1942
1943
				if ($mode == 'style')
1944
				{
1945
					$path = preg_replace('#[^\w-]+#', '_', $style_row['style_name']);
1946
				}
1947
				else
1948
				{
1949
					$path = $style_row[$mode . '_path'];
1950
				}
1951
1952
				if ($format == 'zip')
1953
				{
1954
					$compress = new compress_zip('w', $phpbb_root_path . "store/$path$ext");
1955
				}
1956
				else
1957
				{
1958
					$compress = new compress_tar('w', $phpbb_root_path . "store/$path$ext", $ext);
1959
				}
1960
1961
				if (sizeof($files))
1962
				{
1963
					foreach ($files as $file_ary)
1964
					{
1965
						$compress->add_file($file_ary['src'], $file_ary['prefix-'], $file_ary['prefix+'], $file_ary['exclude']);
1966
					}
1967
				}
1968
1969
				if (sizeof($data))
1970
				{
1971
					foreach ($data as $data_ary)
1972
					{
1973
						$compress->add_data($data_ary['src'], $data_ary['prefix']);
1974
					}
1975
				}
1976
1977
				$compress->close();
1978
1979
				add_log('admin', 'LOG_' . $l_prefix . '_EXPORT', $style_row[$mode . '_name']);
1980
1981
				if (!$store)
1982
				{
1983
					$compress->download($path);
1984
					@unlink("{$phpbb_root_path}store/$path$ext");
1985
					exit;
1986
				}
1987
1988
				trigger_error(sprintf($user->lang[$l_prefix . '_EXPORTED'], "store/$path$ext") . adm_back_link($this->u_action));
1989
			}
1990
		}
1991
1992
		$sql = "SELECT {$mode}_id, {$mode}_name
1993
			FROM " . (($mode == 'style') ? STYLES_TABLE : $sql_from) . "
1994
			WHERE {$mode}_id = $style_id";
1995
		$result = $db->sql_query($sql);
1996
		$style_row = $db->sql_fetchrow($result);
1997
		$db->sql_freeresult($result);
1998
1999
		if (!$style_row)
2000
		{
2001
			trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
2002
		}
2003
2004
		$this->page_title = $l_prefix . '_EXPORT';
2005
2006
		$format_buttons = '';
2007
		foreach ($methods as $method)
2008
		{
2009
			$format_buttons .= '<label><input type="radio"' . ((!$format_buttons) ? ' id="format"' : '') . ' class="radio" value="' . $method . '" name="format"' . (($method == $format) ? ' checked="checked"' : '') . ' /> ' . $method . '</label>';
2010
		}
2011
2012
		$template->assign_vars(array(
2013
			'S_EXPORT'		=> true,
2014
			'S_ERROR_MSG'	=> (sizeof($error)) ? true : false,
2015
			'S_STYLE'		=> ($mode == 'style') ? true : false,
2016
2017
			'L_TITLE'		=> $user->lang[$this->page_title],
2018
			'L_EXPLAIN'		=> $user->lang[$this->page_title . '_EXPLAIN'],
2019
			'L_NAME'		=> $user->lang[$l_prefix . '_NAME'],
2020
2021
			'U_ACTION'		=> $this->u_action . '&amp;action=export&amp;id=' . $style_id,
2022
			'U_BACK'		=> $this->u_action,
2023
2024
			'ERROR_MSG'			=> (sizeof($error)) ? implode('<br />', $error) : '',
2025
			'NAME'				=> $style_row[$mode . '_name'],
2026
			'FORMAT_BUTTONS'	=> $format_buttons)
2027
		);
2028
	}
2029
2030
	/**
2031
	* Display details
2032
	*/
2033
	function details($mode, $style_id)
2034
	{
2035
		global $template, $db, $config, $user, $safe_mode, $cache, $phpbb_root_path;
2036
2037
		$update = (isset($_POST['update'])) ? true : false;
2038
		$l_type = strtoupper($mode);
2039
2040
		$error = array();
2041
		$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2042
2043
		switch ($mode)
2044
		{
2045
			case 'style':
2046
				$sql_from = STYLES_TABLE;
2047
			break;
2048
2049
			case 'template':
2050
				$sql_from = STYLES_TEMPLATE_TABLE;
2051
			break;
2052
2053
			case 'theme':
2054
				$sql_from = STYLES_THEME_TABLE;
2055
			break;
2056
2057
			case 'imageset':
2058
				$sql_from = STYLES_IMAGESET_TABLE;
2059
			break;
2060
		}
2061
2062
		$sql = "SELECT *
2063
			FROM $sql_from
2064
			WHERE {$mode}_id = $style_id";
2065
		$result = $db->sql_query($sql);
2066
		$style_row = $db->sql_fetchrow($result);
2067
		$db->sql_freeresult($result);
2068
2069
		if (!$style_row)
2070
		{
2071
			trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2072
		}
2073
2074
		$style_row['style_default'] = ($mode == 'style' && $config['default_style'] == $style_id) ? 1 : 0;
2075
2076
		if ($update)
2077
		{
2078
			$name = utf8_normalize_nfc(request_var('name', '', true));
2079
			$copyright = utf8_normalize_nfc(request_var('copyright', '', true));
2080
2081
			$template_id = request_var('template_id', 0);
2082
			$theme_id = request_var('theme_id', 0);
2083
			$imageset_id = request_var('imageset_id', 0);
2084
2085
			$style_active = request_var('style_active', 0);
2086
			$style_default = request_var('style_default', 0);
2087
			$store_db = request_var('store_db', 0);
2088
2089
			if ($mode == 'style' && (!$template_id || !$theme_id || !$imageset_id))
2090
			{
2091
				$error[] = $user->lang['STYLE_ERR_NO_IDS'];
2092
			}
2093
2094
			if ($mode == 'style' && $style_row['style_active'] && !$style_active && $config['default_style'] == $style_id)
2095
			{
2096
				$error[] = $user->lang['DEACTIVATE_DEFAULT'];
2097
			}
2098
2099
			if (!$name)
2100
			{
2101
				$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
2102
			}
2103
2104
			if ($mode === 'theme' || $mode === 'template')
2105
			{
2106
				// a rather elaborate check we have to do here once to avoid trouble later
2107
				$check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
2108
				if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !@is_writable($check)))
2109
				{
2110
					$error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
2111
					$store_db = 1;
2112
				}
2113
2114
				// themes which have to be parsed have to go into db
2115
				if ($mode == 'theme')
2116
				{
2117
					$cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg");
2118
2119
					if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db)
2120
					{
2121
						$error[] = $user->lang['EDIT_THEME_STORE_PARSED'];
2122
						$store_db = 1;
2123
					}
2124
				}
2125
			}
2126
			
2127
			if (!sizeof($error))
2128
			{
2129
				// Check length settings
2130
				if (utf8_strlen($name) > 30)
2131
				{
2132
					$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
2133
				}
2134
2135
				if (utf8_strlen($copyright) > 60)
2136
				{
2137
					$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
2138
				}
2139
			}
2140
		}
2141
2142
		if ($update && sizeof($error))
2143
		{
2144
			$style_row = array_merge($style_row, array(
2145
				'template_id'			=> $template_id,
2146
				'theme_id'				=> $theme_id,
2147
				'imageset_id'			=> $imageset_id,
2148
				'style_active'			=> $style_active,
2149
				$mode . '_storedb'		=> $store_db,
2150
				$mode . '_name'			=> $name,
2151
				$mode . '_copyright'	=> $copyright)
2152
			);
2153
		}
2154
2155
		// User has submitted form and no errors have occurred
2156
		if ($update && !sizeof($error))
2157
		{
2158
			$sql_ary = array(
2159
				$mode . '_name'			=> $name,
2160
				$mode . '_copyright'	=> $copyright
2161
			);
2162
2163
			switch ($mode)
2164
			{
2165
				case 'style':
2166
2167
					$sql_ary += array(
2168
						'template_id'		=> (int) $template_id,
2169
						'theme_id'			=> (int) $theme_id,
2170
						'imageset_id'		=> (int) $imageset_id,
2171
						'style_active'		=> (int) $style_active,
2172
					);
2173
				break;
2174
2175
				case 'imageset':
2176
				break;
2177
2178
				case 'theme':
2179
2180
					if ($style_row['theme_storedb'] != $store_db)
2181
					{
2182
						$theme_data = '';
2183
2184
						if (!$style_row['theme_storedb'])
2185
						{
2186
							$theme_data = $this->db_theme_data($style_row);
2187
						}
2188
						else if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
2189
						{
2190
							$store_db = 1;
2191
							$theme_data = $style_row['theme_data'];
2192
2193
							if ($fp = @fopen("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css", 'wb'))
2194
							{
2195
								$store_db = (@fwrite($fp, str_replace("styles/{$style_row['theme_path']}/theme/", './', $theme_data))) ? 0 : 1;
2196
							}
2197
							fclose($fp);
2198
						}
2199
2200
						$sql_ary += array(
2201
							'theme_mtime'	=> ($store_db) ? filemtime("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css") : 0,
2202
							'theme_storedb'	=> $store_db,
2203
							'theme_data'	=> ($store_db) ? $theme_data : '',
2204
						);
2205
					}
2206
				break;
2207
2208
				case 'template':
2209
2210
					if ($style_row['template_storedb'] != $store_db)
2211
					{
2212
						if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
2213
						{
2214
							$sql = 'SELECT *
2215
								FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2216
								WHERE template_id = $style_id";
2217
							$result = $db->sql_query($sql);
2218
2219
							while ($row = $db->sql_fetchrow($result))
2220
							{
2221
								if (!($fp = @fopen("{$phpbb_root_path}styles/{$style_row['template_path']}/template/" . $row['template_filename'], 'wb')))
2222
								{
2223
									$store_db = 1;
2224
									$error[] = $user->lang['EDIT_TEMPLATE_STORED_DB'];
2225
									break;
2226
								}
2227
2228
								fwrite($fp, $row['template_data']);
2229
								fclose($fp);
2230
							}
2231
							$db->sql_freeresult($result);
2232
2233
							if (!$store_db)
2234
							{
2235
								$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2236
									WHERE template_id = $style_id";
2237
								$db->sql_query($sql);
2238
							}
2239
						}
2240
						else if ($store_db)
2241
						{
2242
							$filelist = filelist("{$phpbb_root_path}styles/{$style_row['template_path']}/template", '', 'html');
2243
							$this->store_templates('insert', $style_id, $style_row['template_path'], $filelist);
2244
						}
2245
						else
2246
						{
2247
							// We no longer store within the db, but are also not able to update the file structure
2248
							// Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache
2249
							$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2250
								WHERE template_id = $style_id";
2251
							$db->sql_query($sql);
2252
						}
2253
2254
						$sql_ary += array(
2255
							'template_storedb'	=> $store_db,
2256
						);
2257
					}
2258
				break;
2259
			}
2260
2261
			if (sizeof($sql_ary))
2262
			{
2263
				$sql = "UPDATE $sql_from
2264
					SET " . $db->sql_build_array('UPDATE', $sql_ary) . "
2265
					WHERE {$mode}_id = $style_id";
2266
				$db->sql_query($sql);
2267
2268
				// Making this the default style?
2269
				if ($mode == 'style' && $style_default)
2270
				{
2271
					set_config('default_style', $style_id);
2272
				}
2273
			}
2274
2275
			$cache->destroy('sql', STYLES_TABLE);
2276
2277
			add_log('admin', 'LOG_' . $l_type . '_EDIT_DETAILS', $name);
2278
			if (sizeof($error))
2279
			{
2280
				trigger_error(implode('<br />', $error) . adm_back_link($this->u_action), E_USER_WARNING);
2281
			}
2282
			else
2283
			{
2284
				trigger_error($user->lang[$l_type . '_DETAILS_UPDATED'] . adm_back_link($this->u_action));
2285
			}
2286
		}
2287
2288
		if ($mode == 'style')
2289
		{
2290
			foreach ($element_ary as $element => $table)
2291
			{
2292
				$sql = "SELECT {$element}_id, {$element}_name
2293
					FROM $table
2294
					ORDER BY {$element}_id ASC";
2295
				$result = $db->sql_query($sql);
2296
2297
				${$element . '_options'} = '';
2298
				while ($row = $db->sql_fetchrow($result))
2299
				{
2300
					$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2301
					${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2302
				}
2303
				$db->sql_freeresult($result);
2304
			}
2305
		}
2306
2307
		$this->page_title = 'EDIT_DETAILS_' . $l_type;
2308
2309
		$template->assign_vars(array(
2310
			'S_DETAILS'				=> true,
2311
			'S_ERROR_MSG'			=> (sizeof($error)) ? true : false,
2312
			'S_STYLE'				=> ($mode == 'style') ? true : false,
2313
			'S_TEMPLATE'			=> ($mode == 'template') ? true : false,
2314
			'S_THEME'				=> ($mode == 'theme') ? true : false,
2315
			'S_IMAGESET'			=> ($mode == 'imageset') ? true : false,
2316
			'S_STORE_DB'			=> (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2317
			'S_STYLE_ACTIVE'		=> (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2318
			'S_STYLE_DEFAULT'		=> (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2319
2320
			'S_TEMPLATE_OPTIONS'	=> ($mode == 'style') ? $template_options : '',
2321
			'S_THEME_OPTIONS'		=> ($mode == 'style') ? $theme_options : '',
2322
			'S_IMAGESET_OPTIONS'	=> ($mode == 'style') ? $imageset_options : '',
2323
2324
			'U_ACTION'		=> $this->u_action . '&amp;action=details&amp;id=' . $style_id,
2325
			'U_BACK'		=> $this->u_action,
2326
2327
			'L_TITLE'				=> $user->lang[$this->page_title],
2328
			'L_EXPLAIN'				=> $user->lang[$this->page_title . '_EXPLAIN'],
2329
			'L_NAME'				=> $user->lang[$l_type . '_NAME'],
2330
			'L_LOCATION'			=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2331
			'L_LOCATION_EXPLAIN'	=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2332
2333
			'ERROR_MSG'		=> (sizeof($error)) ? implode('<br />', $error) : '',
2334
			'NAME'			=> $style_row[$mode . '_name'],
2335
			'COPYRIGHT'		=> $style_row[$mode . '_copyright'],
2336
			)
2337
		);
2338
	}
2339
2340
	/**
2341
	* Load css file contents
2342
	*/
2343
	function load_css_file($path, $filename)
2344
	{
2345
		global $phpbb_root_path;
2346
2347
		$file = "{$phpbb_root_path}styles/$path/theme/$filename";
2348
2349
		if (file_exists($file) && ($content = file_get_contents($file)))
2350
		{
2351
			$content = trim($content);
2352
		}
2353
		else
2354
		{
2355
			$content = '';
2356
		}
2357
2358
		return $content;
2359
	}
2360
2361
	/**
2362
	* Returns a string containing the value that should be used for the theme_data column in the theme database table.
2363
	* Includes contents of files loaded via @import
2364
	*
2365
	* @param array $theme_row is an associative array containing the theme's current database entry
2366
	* @param mixed $stylesheet can either be the new content for the stylesheet or false to load from the standard file
2367
	* @param string $root_path should only be used in case you want to use a different root path than "{$phpbb_root_path}styles/{$theme_row['theme_path']}"
2368
	*
2369
	* @return string Stylesheet data for theme_data column in the theme table
2370
	*/
2371
	function db_theme_data($theme_row, $stylesheet = false, $root_path = '')
2372
	{
2373
		global $phpbb_root_path;
2374
2375
		if (!$root_path)
2376
		{
2377
			$root_path = $phpbb_root_path . 'styles/' . $theme_row['theme_path'];
2378
		}
2379
2380
		if (!$stylesheet)
2381
		{
2382
			$stylesheet = '';
2383
			if (file_exists($root_path . '/theme/stylesheet.css'))
2384
			{
2385
				$stylesheet = file_get_contents($root_path . '/theme/stylesheet.css');
2386
			}
2387
		}
2388
2389
		// Match CSS imports
2390
		$matches = array();
2391
		preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
2392
2393
		if (sizeof($matches))
2394
		{
2395
			foreach ($matches[0] as $idx => $match)
2396
			{
2397
				$stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[1][$idx]), $stylesheet);
2398
			}
2399
		}
2400
2401
		// adjust paths
2402
		return str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet);
2403
	}
2404
2405
	/**
2406
	* Store template files into db
2407
	*/
2408
	function store_templates($mode, $style_id, $template_path, $filelist)
2409
	{
2410
		global $phpbb_root_path, $phpEx, $db;
2411
2412
		$template_path = $template_path . '/template/';
2413
		$includes = array();
2414
		foreach ($filelist as $pathfile => $file_ary)
2415
		{
2416
			foreach ($file_ary as $file)
2417
			{
2418
				if (!($fp = @fopen("{$phpbb_root_path}styles/$template_path$pathfile$file", 'r')))
2419
				{
2420
					trigger_error("Could not open {$phpbb_root_path}styles/$template_path$pathfile$file", E_USER_ERROR);
2421
				}
2422
				$template_data = fread($fp, filesize("{$phpbb_root_path}styles/$template_path$pathfile$file"));
2423
				fclose($fp);
2424
2425
				if (preg_match_all('#<!-- INCLUDE (.*?\.html) -->#is', $template_data, $matches))
2426
				{
2427
					foreach ($matches[1] as $match)
2428
					{
2429
						$includes[trim($match)][] = $file;
2430
					}
2431
				}
2432
			}
2433
		}
2434
2435
		foreach ($filelist as $pathfile => $file_ary)
2436
		{
2437
			foreach ($file_ary as $file)
2438
			{
2439
				// Skip index.
2440
				if (strpos($file, 'index.') === 0)
2441
				{
2442
					continue;
2443
				}
2444
2445
				// We could do this using extended inserts ... but that could be one
2446
				// heck of a lot of data ...
2447
				$sql_ary = array(
2448
					'template_id'			=> (int) $style_id,
2449
					'template_filename'		=> "$pathfile$file",
2450
					'template_included'		=> (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '',
2451
					'template_mtime'		=> (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2452
					'template_data'			=> (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2453
				);
2454
2455
				if ($mode == 'insert')
2456
				{
2457
					$sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
2458
				}
2459
				else
2460
				{
2461
					$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
2462
						WHERE template_id = $style_id
2463
							AND template_filename = '" . $db->sql_escape("$pathfile$file") . "'";
2464
				}
2465
				$db->sql_query($sql);
2466
			}
2467
		}
2468
	}
2469
2470
	/**
2471
	* Returns an array containing all template filenames for one template that are currently cached.
2472
	*
2473
	* @param string $template_path contains the name of the template's folder in /styles/
2474
	*
2475
	* @return array of filenames that exist in /styles/$template_path/template/ (without extension!)
2476
	*/
2477
	function template_cache_filelist($template_path)
2478
	{
2479
		global $phpbb_root_path, $phpEx, $user;
2480
2481
		$cache_prefix = 'tpl_' . $template_path;
2482
2483
		if (!($dp = @opendir("{$phpbb_root_path}cache")))
2484
		{
2485
			trigger_error($user->lang['TEMPLATE_ERR_CACHE_READ'] . adm_back_link($this->u_action), E_USER_WARNING);
2486
		}
2487
2488
		$file_ary = array();
2489
		while ($file = readdir($dp))
2490
		{
2491
			if ($file[0] == '.')
2492
			{
2493
				continue;
2494
			}
2495
2496
			if (is_file($phpbb_root_path . 'cache/' . $file) && (strpos($file, $cache_prefix) === 0))
2497
			{
2498
				$file_ary[] = str_replace('.', '/', preg_replace('#^' . preg_quote($cache_prefix, '#') . '_(.*?)\.html\.' . $phpEx . '$#i', '\1', $file));
2499
			}
2500
		}
2501
		closedir($dp);
2502
2503
		return $file_ary;
2504
	}
2505
2506
	/**
2507
	* Destroys cached versions of template files
2508
	*
2509
	* @param array $template_row contains the template's row in the STYLES_TEMPLATE_TABLE database table
2510
	* @param mixed $file_ary is optional and may contain an array of template file names which should be refreshed in the cache.
2511
	*	The file names should be the original template file names and not the cache file names.
2512
	*/
2513
	function clear_template_cache($template_row, $file_ary = false)
2514
	{
2515
		global $phpbb_root_path, $phpEx, $user;
2516
2517
		$cache_prefix = 'tpl_' . $template_row['template_path'];
2518
2519
		if (!$file_ary || !is_array($file_ary))
2520
		{
2521
			$file_ary = $this->template_cache_filelist($template_row['template_path']);
2522
			$log_file_list = $user->lang['ALL_FILES'];
2523
		}
2524
		else
2525
		{
2526
			$log_file_list = implode(', ', $file_ary);
2527
		}
2528
2529
		foreach ($file_ary as $file)
2530
		{
2531
			$file = str_replace('/', '.', $file);
2532
2533
			$file = "{$phpbb_root_path}cache/{$cache_prefix}_$file.html.$phpEx";
2534
			if (file_exists($file) && is_file($file))
2535
			{
2536
				@unlink($file);
2537
			}
2538
		}
2539
		unset($file_ary);
2540
2541
		add_log('admin', 'LOG_TEMPLATE_CACHE_CLEARED', $template_row['template_name'], $log_file_list);
2542
	}
2543
2544
	/**
2545
	* Install Style/Template/Theme/Imageset
2546
	*/
2547
	function install($mode)
2548
	{
2549
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2550
2551
		$l_type = strtoupper($mode);
2552
2553
		$error = $installcfg = $style_row = array();
2554
		$root_path = $cfg_file = '';
2555
		$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2556
2557
		$install_path = request_var('path', '');
2558
		$update = (isset($_POST['update'])) ? true : false;
2559
2560
		// Installing, obtain cfg file contents
2561
		if ($install_path)
2562
		{
2563
			$root_path = $phpbb_root_path . 'styles/' . $install_path . '/';
2564
			$cfg_file = ($mode == 'style') ? "$root_path$mode.cfg" : "$root_path$mode/$mode.cfg";
2565
2566
			if (!file_exists($cfg_file))
2567
			{
2568
				$error[] = $user->lang[$l_type . '_ERR_NOT_' . $l_type];
2569
			}
2570
			else
2571
			{
2572
				$installcfg = parse_cfg_file($cfg_file);
2573
			}
2574
		}
2575
2576
		// Installing
2577
		if (sizeof($installcfg))
2578
		{
2579
			$name		= $installcfg['name'];
2580
			$copyright	= $installcfg['copyright'];
2581
			$version	= $installcfg['version'];
2582
2583
			$style_row = array(
2584
				$mode . '_id'			=> 0,
2585
				$mode . '_name'			=> '',
2586
				$mode . '_copyright'	=> ''
2587
			);
2588
2589
			switch ($mode)
2590
			{
2591
				case 'style':
2592
2593
					$style_row = array(
2594
						'style_id'			=> 0,
2595
						'style_name'		=> $installcfg['name'],
2596
						'style_copyright'	=> $installcfg['copyright']
2597
					);
2598
2599
					$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2600
					$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2601
					$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2602
2603
					// Check to see if each element is already installed, if it is grab the id
2604
					foreach ($element_ary as $element => $table)
2605
					{
2606
						$style_row = array_merge($style_row, array(
2607
							$element . '_id'			=> 0,
2608
							$element . '_name'			=> '',
2609
							$element . '_copyright'		=> '')
2610
						);
2611
2612
			 			$this->test_installed($element, $error, (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . $reqd_template . '/' : $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
2613
2614
						if (!$style_row[$element . '_name'])
2615
						{
2616
							$style_row[$element . '_name'] = $reqd_template;
2617
						}
2618
					}
2619
2620
				break;
2621
2622
				case 'template':
2623
					$this->test_installed('template', $error, $root_path, false, $style_row['template_id'], $style_row['template_name'], $style_row['template_copyright']);
2624
				break;
2625
2626
				case 'theme':
2627
					$this->test_installed('theme', $error, $root_path, false, $style_row['theme_id'], $style_row['theme_name'], $style_row['theme_copyright']);
2628
				break;
2629
2630
				case 'imageset':
2631
					$this->test_installed('imageset', $error, $root_path, false, $style_row['imageset_id'], $style_row['imageset_name'], $style_row['imageset_copyright']);
2632
				break;
2633
			}
2634
		}
2635
		else
2636
		{
2637
			trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2638
		}
2639
2640
		$style_row['store_db'] = request_var('store_db', 0);
2641
		$style_row['style_active'] = request_var('style_active', 1);
2642
		$style_row['style_default'] = request_var('style_default', 0);
2643
2644
		// User has submitted form and no errors have occurred
2645
		if ($update && !sizeof($error))
2646
		{
2647
			if ($mode == 'style')
2648
			{
2649
				foreach ($element_ary as $element => $table)
2650
				{
2651
					${$element . '_root_path'} = (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . ${'reqd_' . $element} . '/' : false;
2652
					${$element . '_path'} = (${'reqd_' . $element}) ? ${'reqd_' . $element} : false;
2653
				}
2654
				$this->install_style($error, 'install', $root_path, $style_row['style_id'], $style_row['style_name'], $install_path, $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row, $template_root_path, $template_path, $theme_root_path, $theme_path, $imageset_root_path, $imageset_path);
2655
			}
2656
			else
2657
			{
2658
				$style_row['store_db'] = $this->install_element($mode, $error, 'install', $root_path, $style_row[$mode . '_id'], $style_row[$mode . '_name'], $install_path, $style_row[$mode . '_copyright'], $style_row['store_db']);
2659
			}
2660
2661
			if (!sizeof($error))
2662
			{
2663
				$cache->destroy('sql', STYLES_TABLE);
2664
2665
				$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
2666
				trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
2667
			}
2668
		}
2669
2670
		$this->page_title = 'INSTALL_' . $l_type;
2671
2672
		$template->assign_vars(array(
2673
			'S_DETAILS'			=> true,
2674
			'S_INSTALL'			=> true,
2675
			'S_ERROR_MSG'		=> (sizeof($error)) ? true : false,
2676
			'S_STYLE'			=> ($mode == 'style') ? true : false,
2677
			'S_TEMPLATE'		=> ($mode == 'template') ? true : false,
2678
			'S_THEME'			=> ($mode == 'theme') ? true : false,
2679
2680
			'S_STORE_DB'			=> (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2681
			'S_STYLE_ACTIVE'		=> (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2682
			'S_STYLE_DEFAULT'		=> (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2683
2684
			'U_ACTION'			=> $this->u_action . "&amp;action=install&amp;path=" . urlencode($install_path),
2685
			'U_BACK'			=> $this->u_action,
2686
2687
			'L_TITLE'				=> $user->lang[$this->page_title],
2688
			'L_EXPLAIN'				=> $user->lang[$this->page_title . '_EXPLAIN'],
2689
			'L_NAME'				=> $user->lang[$l_type . '_NAME'],
2690
			'L_LOCATION'			=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2691
			'L_LOCATION_EXPLAIN'	=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2692
2693
			'ERROR_MSG'			=> (sizeof($error)) ? implode('<br />', $error) : '',
2694
			'NAME'				=> $style_row[$mode . '_name'],
2695
			'COPYRIGHT'			=> $style_row[$mode . '_copyright'],
2696
			'TEMPLATE_NAME'		=> ($mode == 'style') ? $style_row['template_name'] : '',
2697
			'THEME_NAME'		=> ($mode == 'style') ? $style_row['theme_name'] : '',
2698
			'IMAGESET_NAME'		=> ($mode == 'style') ? $style_row['imageset_name'] : '')
2699
		);
2700
	}
2701
2702
	/**
2703
	* Add new style
2704
	*/
2705
	function add($mode)
2706
	{
2707
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2708
2709
		$l_type = strtoupper($mode);
2710
		$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2711
		$error = array();
2712
2713
		$style_row = array(
2714
			$mode . '_name'			=> utf8_normalize_nfc(request_var('name', '', true)),
2715
			$mode . '_copyright'	=> utf8_normalize_nfc(request_var('copyright', '', true)),
2716
			'template_id'			=> 0,
2717
			'theme_id'				=> 0,
2718
			'imageset_id'			=> 0,
2719
			'store_db'				=> request_var('store_db', 0),
2720
			'style_active'			=> request_var('style_active', 1),
2721
			'style_default'			=> request_var('style_default', 0),
2722
		);
2723
2724
		$basis = request_var('basis', 0);
2725
		$update = (isset($_POST['update'])) ? true : false;
2726
2727
		if ($basis)
2728
		{
2729
			switch ($mode)
2730
			{
2731
				case 'style':
2732
					$sql_select = 'template_id, theme_id, imageset_id';
2733
					$sql_from = STYLES_TABLE;
2734
				break;
2735
2736
				case 'template':
2737
					$sql_select = 'template_id';
2738
					$sql_from = STYLES_TEMPLATE_TABLE;
2739
				break;
2740
2741
				case 'theme':
2742
					$sql_select = 'theme_id';
2743
					$sql_from = STYLES_THEME_TABLE;
2744
				break;
2745
2746
				case 'imageset':
2747
					$sql_select = 'imageset_id';
2748
					$sql_from = STYLES_IMAGESET_TABLE;
2749
				break;
2750
			}
2751
2752
			$sql = "SELECT $sql_select
2753
				FROM $sql_from
2754
				WHERE {$mode}_id = $basis";
2755
			$result = $db->sql_query($sql);
2756
			$row = $db->sql_fetchrow($result);
2757
			$db->sql_freeresult($result);
2758
2759
			if (!$row)
2760
			{
2761
				$error[] = $user->lang['NO_' . $l_type];
2762
			}
2763
2764
			if (!sizeof($error))
2765
			{
2766
				$style_row['template_id']	= (isset($row['template_id'])) ? $row['template_id'] : $style_row['template_id'];
2767
				$style_row['theme_id']		= (isset($row['theme_id'])) ? $row['theme_id'] : $style_row['theme_id'];
2768
				$style_row['imageset_id']	= (isset($row['imageset_id'])) ? $row['imageset_id'] : $style_row['imageset_id'];
2769
			}
2770
		}
2771
2772
		if ($update)
2773
		{
2774
			$style_row['template_id'] = request_var('template_id', $style_row['template_id']);
2775
			$style_row['theme_id'] = request_var('theme_id', $style_row['theme_id']);
2776
			$style_row['imageset_id'] = request_var('imageset_id', $style_row['imageset_id']);
2777
2778
			if ($mode == 'style' && (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id']))
2779
			{
2780
				$error[] = $user->lang['STYLE_ERR_NO_IDS'];
2781
			}
2782
		}
2783
2784
		// User has submitted form and no errors have occurred
2785
		if ($update && !sizeof($error))
2786
		{
2787
			if ($mode == 'style')
2788
			{
2789
				$style_row['style_id'] = 0;
2790
2791
				$this->install_style($error, 'add', '', $style_row['style_id'], $style_row['style_name'], '', $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row);
2792
			}
2793
2794
			if (!sizeof($error))
2795
			{
2796
				$cache->destroy('sql', STYLES_TABLE);
2797
2798
				$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
2799
				trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
2800
			}
2801
		}
2802
2803
		if ($mode == 'style')
2804
		{
2805
			foreach ($element_ary as $element => $table)
2806
			{
2807
				$sql = "SELECT {$element}_id, {$element}_name
2808
					FROM $table
2809
					ORDER BY {$element}_id ASC";
2810
				$result = $db->sql_query($sql);
2811
2812
				${$element . '_options'} = '';
2813
				while ($row = $db->sql_fetchrow($result))
2814
				{
2815
					$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2816
					${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2817
				}
2818
				$db->sql_freeresult($result);
2819
			}
2820
		}
2821
2822
		$this->page_title = 'ADD_' . $l_type;
2823
2824
		$template->assign_vars(array(
2825
			'S_DETAILS'			=> true,
2826
			'S_ADD'				=> true,
2827
			'S_ERROR_MSG'		=> (sizeof($error)) ? true : false,
2828
			'S_STYLE'			=> ($mode == 'style') ? true : false,
2829
			'S_TEMPLATE'		=> ($mode == 'template') ? true : false,
2830
			'S_THEME'			=> ($mode == 'theme') ? true : false,
2831
			'S_BASIS'			=> ($basis) ? true : false,
2832
2833
			'S_STORE_DB'			=> (isset($style_row['storedb'])) ? $style_row['storedb'] : 0,
2834
			'S_STYLE_ACTIVE'		=> (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2835
			'S_STYLE_DEFAULT'		=> (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2836
			'S_TEMPLATE_OPTIONS'	=> ($mode == 'style') ? $template_options : '',
2837
			'S_THEME_OPTIONS'		=> ($mode == 'style') ? $theme_options : '',
2838
			'S_IMAGESET_OPTIONS'	=> ($mode == 'style') ? $imageset_options : '',
2839
2840
			'U_ACTION'			=> $this->u_action . '&amp;action=add&amp;basis=' . $basis,
2841
			'U_BACK'			=> $this->u_action,
2842
2843
			'L_TITLE'				=> $user->lang[$this->page_title],
2844
			'L_EXPLAIN'				=> $user->lang[$this->page_title . '_EXPLAIN'],
2845
			'L_NAME'				=> $user->lang[$l_type . '_NAME'],
2846
			'L_LOCATION'			=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2847
			'L_LOCATION_EXPLAIN'	=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2848
2849
			'ERROR_MSG'			=> (sizeof($error)) ? implode('<br />', $error) : '',
2850
			'NAME'				=> $style_row[$mode . '_name'],
2851
			'COPYRIGHT'			=> $style_row[$mode . '_copyright'])
2852
		);
2853
2854
	}
2855
2856
	/**
2857
2858
					$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2859
					$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2860
					$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2861
2862
					// Check to see if each element is already installed, if it is grab the id
2863
					foreach ($element_ary as $element => $table)
2864
					{
2865
						$style_row = array_merge($style_row, array(
2866
							$element . '_id'			=> 0,
2867
							$element . '_name'			=> '',
2868
							$element . '_copyright'		=> '')
2869
						);
2870
2871
			 			$this->test_installed($element, $error, $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
2872
	* Is this element installed? If not, grab its cfg details
2873
	*/
2874
	function test_installed($element, &$error, $root_path, $reqd_name, &$id, &$name, &$copyright)
2875
	{
2876
		global $db, $user;
2877
2878
		switch ($element)
2879
		{
2880
			case 'template':
2881
				$sql_from = STYLES_TEMPLATE_TABLE;
2882
			break;
2883
2884
			case 'theme':
2885
				$sql_from = STYLES_THEME_TABLE;
2886
			break;
2887
2888
			case 'imageset':
2889
				$sql_from = STYLES_IMAGESET_TABLE;
2890
			break;
2891
		}
2892
2893
		$l_element = strtoupper($element);
2894
2895
		$chk_name = ($reqd_name !== false) ? $reqd_name : $name;
2896
2897
		$sql = "SELECT {$element}_id, {$element}_name
2898
			FROM $sql_from
2899
			WHERE {$element}_name = '" . $db->sql_escape($chk_name) . "'";
2900
		$result = $db->sql_query($sql);
2901
2902
		if ($row = $db->sql_fetchrow($result))
2903
		{
2904
			$name = $row[$element . '_name'];
2905
			$id = $row[$element . '_id'];
2906
		}
2907
		else
2908
		{
2909
			if (!($cfg = @file("$root_path$element/$element.cfg")))
2910
			{
2911
				$error[] = sprintf($user->lang['REQUIRES_' . $l_element], $reqd_name);
2912
				return false;
2913
			}
2914
2915
			$cfg = parse_cfg_file("$root_path$element/$element.cfg", $cfg);
2916
2917
			$name = $cfg['name'];
2918
			$copyright = $cfg['copyright'];
2919
			$id = 0;
2920
2921
			unset($cfg);
2922
		}
2923
		$db->sql_freeresult($result);
2924
	}
2925
2926
	/**
2927
	* Install/Add style
2928
	*/
2929
	function install_style(&$error, $action, $root_path, &$id, $name, $path, $copyright, $active, $default, &$style_row, $template_root_path = false, $template_path = false, $theme_root_path = false, $theme_path = false, $imageset_root_path = false, $imageset_path = false)
2930
	{
2931
		global $config, $db, $user;
2932
2933
		$element_ary = array('template', 'theme', 'imageset');
2934
2935
		if (!$name)
2936
		{
2937
			$error[] = $user->lang['STYLE_ERR_STYLE_NAME'];
2938
		}
2939
2940
		// Check length settings
2941
		if (utf8_strlen($name) > 30)
2942
		{
2943
			$error[] = $user->lang['STYLE_ERR_NAME_LONG'];
2944
		}
2945
2946
		if (utf8_strlen($copyright) > 60)
2947
		{
2948
			$error[] = $user->lang['STYLE_ERR_COPY_LONG'];
2949
		}
2950
2951
		// Check if the name already exist
2952
		$sql = 'SELECT style_id
2953
			FROM ' . STYLES_TABLE . "
2954
			WHERE style_name = '" . $db->sql_escape($name) . "'";
2955
		$result = $db->sql_query($sql);
2956
		$row = $db->sql_fetchrow($result);
2957
		$db->sql_freeresult($result);
2958
2959
		if ($row)
2960
		{
2961
			$error[] = $user->lang['STYLE_ERR_NAME_EXIST'];
2962
		}
2963
2964
		if (sizeof($error))
2965
		{
2966
			return false;
2967
		}
2968
2969
		foreach ($element_ary as $element)
2970
		{
2971
			// Zero id value ... need to install element ... run usual checks
2972
			// and do the install if necessary
2973
			if (!$style_row[$element . '_id'])
2974
			{
2975
				$this->install_element($element, $error, $action, (${$element . '_root_path'}) ? ${$element . '_root_path'} : $root_path, $style_row[$element . '_id'], $style_row[$element . '_name'], (${$element . '_path'}) ? ${$element . '_path'} : $path, $style_row[$element . '_copyright']);
2976
			}
2977
		}
2978
2979
		if (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id'])
2980
		{
2981
			$error[] = $user->lang['STYLE_ERR_NO_IDS'];
2982
		}
2983
2984
		if (sizeof($error))
2985
		{
2986
			return false;
2987
		}
2988
2989
		$db->sql_transaction('begin');
2990
2991
		$sql_ary = array(
2992
			'style_name'		=> $name,
2993
			'style_copyright'	=> $copyright,
2994
			'style_active'		=> (int) $active,
2995
			'template_id'		=> (int) $style_row['template_id'],
2996
			'theme_id'			=> (int) $style_row['theme_id'],
2997
			'imageset_id'		=> (int) $style_row['imageset_id'],
2998
		);
2999
3000
		$sql = 'INSERT INTO ' . STYLES_TABLE . '
3001
			' . $db->sql_build_array('INSERT', $sql_ary);
3002
		$db->sql_query($sql);
3003
3004
		$id = $db->sql_nextid();
3005
3006
		if ($default)
3007
		{
3008
			$sql = 'UPDATE ' . USERS_TABLE . "
3009
				SET user_style = $id
3010
				WHERE user_style = " . $config['default_style'];
3011
			$db->sql_query($sql);
3012
3013
			set_config('default_style', $id);
3014
		}
3015
3016
		$db->sql_transaction('commit');
3017
3018
		add_log('admin', 'LOG_STYLE_ADD', $name);
3019
	}
3020
3021
	/**
3022
	* Install/add an element, doing various checks as we go
3023
	*/
3024
	function install_element($mode, &$error, $action, $root_path, &$id, $name, $path, $copyright, $store_db = 0)
3025
	{
3026
		global $phpbb_root_path, $db, $user;
3027
3028
		switch ($mode)
3029
		{
3030
			case 'template':
3031
				$sql_from = STYLES_TEMPLATE_TABLE;
3032
			break;
3033
3034
			case 'theme':
3035
				$sql_from = STYLES_THEME_TABLE;
3036
			break;
3037
3038
			case 'imageset':
3039
				$sql_from = STYLES_IMAGESET_TABLE;
3040
			break;
3041
		}
3042
3043
		$l_type = strtoupper($mode);
3044
3045
		if (!$name)
3046
		{
3047
			$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
3048
		}
3049
3050
		// Check length settings
3051
		if (utf8_strlen($name) > 30)
3052
		{
3053
			$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
3054
		}
3055
3056
		if (utf8_strlen($copyright) > 60)
3057
		{
3058
			$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
3059
		}
3060
3061
		// Check if the name already exist
3062
		$sql = "SELECT {$mode}_id
3063
			FROM $sql_from
3064
			WHERE {$mode}_name = '" . $db->sql_escape($name) . "'";
3065
		$result = $db->sql_query($sql);
3066
		$row = $db->sql_fetchrow($result);
3067
		$db->sql_freeresult($result);
3068
3069
		if ($row)
3070
		{
3071
			// If it exist, we just use the style on installation
3072
			if ($action == 'install')
3073
			{
3074
				$id = $row[$mode . '_id'];
3075
				return false;
3076
			}
3077
3078
			$error[] = $user->lang[$l_type . '_ERR_NAME_EXIST'];
3079
		}
3080
3081
		if (sizeof($error))
3082
		{
3083
			return false;
3084
		}
3085
3086
		$sql_ary = array(
3087
			$mode . '_name'			=> $name,
3088
			$mode . '_copyright'	=> $copyright,
3089
			$mode . '_path'			=> $path,
3090
		);
3091
3092
		switch ($mode)
3093
		{
3094
			case 'template':
3095
				// We check if the template author defined a different bitfield
3096
				$cfg_data = parse_cfg_file("$root_path$mode/template.cfg");
3097
3098
				if (!empty($cfg_data['template_bitfield']))
3099
				{
3100
					$sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield'];
3101
				}
3102
				else
3103
				{
3104
					$sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD;
3105
				}
3106
3107
				// We set a pre-defined bitfield here which we may use further in 3.2
3108
				$sql_ary += array(
3109
					'template_storedb'	=> $store_db
3110
				);
3111
			break;
3112
3113
			case 'theme':
3114
				// We are only interested in the theme configuration for now
3115
				$theme_cfg = parse_cfg_file("{$phpbb_root_path}styles/$path/theme/theme.cfg");
3116
3117
				if (isset($theme_cfg['parse_css_file']) && $theme_cfg['parse_css_file'])
3118
				{
3119
					$store_db = 1;
3120
				}
3121
3122
				$sql_ary += array(
3123
					'theme_storedb'	=> $store_db,
3124
					'theme_data'	=> ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '',
3125
					'theme_mtime'	=> (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css")
3126
				);
3127
			break;
3128
3129
			// all the heavy lifting is done later
3130
			case 'imageset':
3131
			break;
3132
		}
3133
3134
		$db->sql_transaction('begin');
3135
3136
		$sql = "INSERT INTO $sql_from
3137
			" . $db->sql_build_array('INSERT', $sql_ary);
3138
		$db->sql_query($sql);
3139
3140
		$id = $db->sql_nextid();
3141
3142
		if ($mode == 'template' && $store_db)
3143
		{
3144
			$filelist = filelist("{$root_path}template", '', 'html');
3145
			$this->store_templates('insert', $id, $path, $filelist);
3146
		}
3147
		else if ($mode == 'imageset')
3148
		{
3149
			$cfg_data = parse_cfg_file("$root_path$mode/imageset.cfg");
3150
3151
			$imageset_definitions = array();
3152
			foreach ($this->imageset_keys as $topic => $key_array)
3153
			{
3154
				$imageset_definitions = array_merge($imageset_definitions, $key_array);
3155
			}
3156
3157
			foreach ($cfg_data as $key => $value)
3158
			{
3159
				if (strpos($value, '*') !== false)
3160
				{
3161
					if (substr($value, -1, 1) === '*')
3162
					{
3163
						list($image_filename, $image_height) = explode('*', $value);
3164
						$image_width = 0;
3165
					}
3166
					else
3167
					{
3168
						list($image_filename, $image_height, $image_width) = explode('*', $value);
3169
					}
3170
				}
3171
				else
3172
				{
3173
					$image_filename = $value;
3174
					$image_height = $image_width = 0;
3175
				}
3176
3177
				if (strpos($key, 'img_') === 0 && $image_filename)
3178
				{
3179
					$key = substr($key, 4);
3180
					if (in_array($key, $imageset_definitions))
3181
					{
3182
						$sql_ary = array(
3183
							'image_name'		=> $key,
3184
							'image_filename'	=> str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)),
3185
							'image_height'		=> (int) $image_height,
3186
							'image_width'		=> (int) $image_width,
3187
							'imageset_id'		=> (int) $id,
3188
							'image_lang'		=> '',
3189
						);
3190
						$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3191
					}
3192
				}
3193
			}
3194
			unset($cfg_data);
3195
3196
			$sql = 'SELECT lang_dir
3197
				FROM ' . LANG_TABLE;
3198
			$result = $db->sql_query($sql);
3199
3200
			while ($row = $db->sql_fetchrow($result))
3201
			{
3202
				if (@file_exists("$root_path$mode/{$row['lang_dir']}/imageset.cfg"))
3203
				{
3204
					$cfg_data_imageset_data = parse_cfg_file("$root_path$mode/{$row['lang_dir']}/imageset.cfg");
3205
					foreach ($cfg_data_imageset_data as $image_name => $value)
3206
					{
3207
						if (strpos($value, '*') !== false)
3208
						{
3209
							if (substr($value, -1, 1) === '*')
3210
							{
3211
								list($image_filename, $image_height) = explode('*', $value);
3212
								$image_width = 0;
3213
							}
3214
							else
3215
							{
3216
								list($image_filename, $image_height, $image_width) = explode('*', $value);
3217
							}
3218
						}
3219
						else
3220
						{
3221
							$image_filename = $value;
3222
							$image_height = $image_width = 0;
3223
						}
3224
3225
						if (strpos($image_name, 'img_') === 0 && $image_filename)
3226
						{
3227
							$image_name = substr($image_name, 4);
3228
							if (in_array($image_name, $imageset_definitions))
3229
							{
3230
								$sql_ary = array(
3231
									'image_name'		=> $image_name,
3232
									'image_filename'	=> $image_filename,
3233
									'image_height'		=> (int) $image_height,
3234
									'image_width'		=> (int) $image_width,
3235
									'imageset_id'		=> (int) $id,
3236
									'image_lang'		=> $row['lang_dir'],
3237
								);
3238
								$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3239
							}
3240
						}
3241
					}
3242
					unset($cfg_data_imageset_data);
3243
				}
3244
			}
3245
			$db->sql_freeresult($result);
3246
		}
3247
3248
		$db->sql_transaction('commit');
3249
3250
		$log = ($store_db) ? 'LOG_' . $l_type . '_ADD_DB' : 'LOG_' . $l_type . '_ADD_FS';
3251
		add_log('admin', $log, $name);
3252
3253
		// Return store_db in case it had to be altered
3254
		return $store_db;
3255
	}
3256
3257
}
3258
3259
?>