phpBB
Statistics
| Revision:

root / branches / phpBB-3_0_0 / phpBB / includes / acp / acp_styles.php

History | View | Annotate | Download (114.8 kB)

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