Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 553
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
acp_icons
0.00% covered (danger)
0.00%
0 / 551
0.00% covered (danger)
0.00%
0 / 2
38612
0.00% covered (danger)
0.00%
0 / 1
 main
0.00% covered (danger)
0.00%
0 / 544
0.00% covered (danger)
0.00%
0 / 1
38220
 item_count
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14/**
15* @ignore
16*/
17if (!defined('IN_PHPBB'))
18{
19    exit;
20}
21
22/**
23  * @todo {smilies} check regular expressions for special char replacements (stored specialchared in db)
24  */
25class acp_icons
26{
27    var $u_action;
28
29    function main($id, $mode)
30    {
31        global $db, $user, $template, $cache;
32        global $config, $phpbb_root_path;
33        global $request, $phpbb_container;
34
35        $user->add_lang('acp/posting');
36
37        // Set up general vars
38        $action = $request->variable('action', '');
39        $action = (isset($_POST['add'])) ? 'add' : $action;
40        $action = (isset($_POST['edit'])) ? 'edit' : $action;
41        $action = (isset($_POST['import'])) ? 'import' : $action;
42        $icon_id = $request->variable('id', 0);
43
44        $form_key = 'acp_icons';
45        add_form_key($form_key);
46
47        $mode = ($mode == 'smilies') ? 'smilies' : 'icons';
48
49        $this->tpl_name = 'acp_icons';
50
51        // What are we working on?
52        switch ($mode)
53        {
54            case 'smilies':
55                $table = SMILIES_TABLE;
56                $lang = 'SMILIES';
57                $fields = 'smiley';
58                $img_path = $config['smilies_path'];
59            break;
60
61            case 'icons':
62                $table = ICONS_TABLE;
63                $lang = 'ICONS';
64                $fields = 'icons';
65                $img_path = $config['icons_path'];
66            break;
67        }
68
69        $this->page_title = 'ACP_' . $lang;
70
71        // Clear some arrays
72        $_images = $_paks = array();
73        $notice = '';
74
75        // Grab file list of paks and images
76        if ($action == 'edit' || $action == 'add' || $action == 'import')
77        {
78            $imglist = filelist($phpbb_root_path . $img_path, '');
79
80            foreach ($imglist as $path => $img_ary)
81            {
82                if (empty($img_ary))
83                {
84                    continue;
85                }
86
87                asort($img_ary, SORT_STRING);
88
89                foreach ($img_ary as $img)
90                {
91                    $img_size = getimagesize($phpbb_root_path . $img_path . '/' . $path . $img);
92
93                    if ($img_size)
94                    {
95                        if (!$img_size[0] || !$img_size[1] || strlen($img) > 255)
96                        {
97                            continue;
98                        }
99
100                        // adjust the width and height to be lower than 128px while perserving the aspect ratio (for icons)
101                        if ($mode == 'icons')
102                        {
103                            if ($img_size[0] > 127 && $img_size[0] > $img_size[1])
104                            {
105                                $img_size[1] = (int) ($img_size[1] * (127 / $img_size[0]));
106                                $img_size[0] = 127;
107                            }
108                            else if ($img_size[1] > 127)
109                            {
110                                $img_size[0] = (int) ($img_size[0] * (127 / $img_size[1]));
111                                $img_size[1] = 127;
112                            }
113                        }
114                    }
115                    else
116                    {
117                        // getimagesize can't read the dimensions of the SVG files
118                        // https://bugs.php.net/bug.php?id=71517
119                        $xml_get = simplexml_load_file($phpbb_root_path . $img_path . '/' . $path . $img);
120
121                        $svg_width = intval($xml_get['width']);
122                        $svg_height = intval($xml_get['height']);
123                    }
124
125                    $_images[$path . $img]['file'] = $path . $img;
126
127                    // Give SVG a fallback on failure
128                    $_images[$path . $img]['width'] = $img_size ? $img_size[0] : ($svg_width ?: 32);
129                    $_images[$path . $img]['height'] = $img_size ? $img_size[1] : ($svg_height ?: 32);
130                }
131            }
132            unset($imglist);
133
134            if ($dir = @opendir($phpbb_root_path . $img_path))
135            {
136                while (($file = readdir($dir)) !== false)
137                {
138                    if (is_file($phpbb_root_path . $img_path . '/' . $file) && preg_match('#\.pak$#i', $file))
139                    {
140                        $_paks[] = $file;
141                    }
142                }
143                closedir($dir);
144
145                if (!empty($_paks))
146                {
147                    asort($_paks, SORT_STRING);
148                }
149            }
150        }
151
152        // What shall we do today? Oops, I believe that's trademarked ...
153        switch ($action)
154        {
155            case 'edit':
156                unset($_images);
157                $_images = array();
158
159            // no break;
160
161            case 'add':
162
163                $smilies = $default_row = array();
164                $smiley_options = '';
165
166                if ($action == 'add' && $mode == 'smilies')
167                {
168                    $sql = 'SELECT *
169                        FROM ' . SMILIES_TABLE . '
170                        ORDER BY smiley_order';
171                    $result = $db->sql_query($sql);
172
173                    while ($row = $db->sql_fetchrow($result))
174                    {
175                        if (empty($smilies[$row['smiley_url']]))
176                        {
177                            $smilies[$row['smiley_url']] = $row;
178                        }
179                    }
180                    $db->sql_freeresult($result);
181
182                    if (count($smilies))
183                    {
184                        foreach ($smilies as $row)
185                        {
186                            $selected = false;
187
188                            if (!$smiley_options)
189                            {
190                                $selected = true;
191                                $default_row = $row;
192                            }
193                            $smiley_options .= '<option value="' . $row['smiley_url'] . '"' . (($selected) ? ' selected="selected"' : '') . '>' . $row['smiley_url'] . '</option>';
194
195                            $template->assign_block_vars('smile', array(
196                                'SMILEY_URL'    => addslashes($row['smiley_url']),
197                                'CODE'            => addslashes($row['code']),
198                                'EMOTION'        => addslashes($row['emotion']),
199                                'WIDTH'            => $row['smiley_width'],
200                                'HEIGHT'        => $row['smiley_height'],
201                                'ORDER'            => $row['smiley_order'] + 1,
202                            ));
203                        }
204                    }
205                }
206
207                $sql = "SELECT *
208                    FROM $table
209                    ORDER BY {$fields}_order " . (($icon_id || $action == 'add') ? 'DESC' : 'ASC');
210                $result = $db->sql_query($sql);
211
212                $data = array();
213                $after = false;
214                $order_lists = array('', '');
215                $add_order_lists = array('', '');
216                $display_count = 0;
217
218                while ($row = $db->sql_fetchrow($result))
219                {
220                    if ($action == 'add')
221                    {
222                        unset($_images[$row[$fields . '_url']]);
223                    }
224
225                    if ($row[$fields . '_id'] == $icon_id)
226                    {
227                        $after = true;
228                        $data[$row[$fields . '_url']] = $row;
229                    }
230                    else
231                    {
232                        if ($action == 'edit' && !$icon_id)
233                        {
234                            $data[$row[$fields . '_url']] = $row;
235                        }
236
237                        $selected = '';
238                        if (!empty($after))
239                        {
240                            $selected = ' selected="selected"';
241                            $after = false;
242                        }
243                        if ($row['display_on_posting'])
244                        {
245                            $display_count++;
246                        }
247                        $after_txt = ($mode == 'smilies') ? $row['code'] : $row['icons_url'];
248                        $order_lists[$row['display_on_posting']] = '<option value="' . ($row[$fields . '_order'] + 1) . '"' . $selected . '>' . sprintf($user->lang['AFTER_' . $lang], ' -&gt; ' . $after_txt) . '</option>' . $order_lists[$row['display_on_posting']];
249
250                        if (!empty($default_row))
251                        {
252                            $add_order_lists[$row['display_on_posting']] = '<option value="' . ($row[$fields . '_order'] + 1) . '"' . (($row[$fields . '_id'] == $default_row['smiley_id']) ? ' selected="selected"' : '') . '>' . sprintf($user->lang['AFTER_' . $lang], ' -&gt; ' . $after_txt) . '</option>' . $add_order_lists[$row['display_on_posting']];
253                        }
254                    }
255                }
256                $db->sql_freeresult($result);
257
258                $order_list = '<option value="1"' . ((!isset($after)) ? ' selected="selected"' : '') . '>' . $user->lang['FIRST'] . '</option>';
259                $add_order_list = '<option value="1">' . $user->lang['FIRST'] . '</option>';
260
261                if ($action == 'add')
262                {
263                    $data = $_images;
264                }
265
266                $colspan = (($mode == 'smilies') ? 7 : 6);
267                $colspan += ($icon_id) ? 1 : 0;
268                $colspan += ($action == 'add') ? 2 : 0;
269
270                $template->assign_vars(array(
271                    'S_EDIT'        => true,
272                    'S_SMILIES'        => ($mode == 'smilies') ? true : false,
273                    'S_ADD'            => ($action == 'add') ? true : false,
274
275                    'S_ORDER_LIST_DISPLAY'        => $order_list . $order_lists[1],
276                    'S_ORDER_LIST_UNDISPLAY'    => $order_list . $order_lists[0],
277                    'S_ORDER_LIST_DISPLAY_COUNT'    => $display_count + 1,
278
279                    'L_TITLE'        => $user->lang['ACP_' . $lang],
280                    'L_EXPLAIN'        => $user->lang['ACP_' . $lang . '_EXPLAIN'],
281                    'L_CONFIG'        => $user->lang[$lang . '_CONFIG'],
282                    'L_URL'            => $user->lang[$lang . '_URL'],
283                    'L_LOCATION'    => $user->lang[$lang . '_LOCATION'],
284                    'L_WIDTH'        => $user->lang[$lang . '_WIDTH'],
285                    'L_HEIGHT'        => $user->lang[$lang . '_HEIGHT'],
286                    'L_ORDER'        => $user->lang[$lang . '_ORDER'],
287                    'L_NO_ICONS'    => $user->lang['NO_' . $lang . '_' . strtoupper($action)],
288
289                    'COLSPAN'        => $colspan,
290                    'ID'            => $icon_id,
291
292                    'U_BACK'        => $this->u_action,
293                    'U_ACTION'        => $this->u_action . '&amp;action=' . (($action == 'add') ? 'create' : 'modify'),
294                ));
295
296                foreach ($data as $img => $img_row)
297                {
298                    $template->assign_block_vars('items', array(
299                        'IMG'        => $img,
300                        'A_IMG'        => addslashes($img),
301                        'IMG_SRC'    => $phpbb_root_path . $img_path . '/' . $img,
302
303                        'CODE'        => ($mode == 'smilies' && isset($img_row['code'])) ? $img_row['code'] : '',
304                        'EMOTION'    => ($mode == 'smilies' && isset($img_row['emotion'])) ? $img_row['emotion'] : '',
305
306                        'S_ID'                => (isset($img_row[$fields . '_id'])) ? true : false,
307                        'ID'                => (isset($img_row[$fields . '_id'])) ? $img_row[$fields . '_id'] : 0,
308                        'WIDTH'                => (!empty($img_row[$fields .'_width'])) ? $img_row[$fields .'_width'] : $img_row['width'],
309                        'HEIGHT'            => (!empty($img_row[$fields .'_height'])) ? $img_row[$fields .'_height'] : $img_row['height'],
310                        'TEXT_ALT'            => ($mode == 'icons' && !empty($img_row['icons_alt'])) ? $img_row['icons_alt'] : $img,
311                        'ALT'                => ($mode == 'icons' && !empty($img_row['icons_alt'])) ? $img_row['icons_alt'] : '',
312                        'POSTING_CHECKED'    => (!empty($img_row['display_on_posting']) || $action == 'add') ? ' checked="checked"' : '',
313                    ));
314                }
315
316                // Ok, another row for adding an addition code for a pre-existing image...
317                if ($action == 'add' && $mode == 'smilies' && count($smilies))
318                {
319                    $template->assign_vars(array(
320                        'S_ADD_CODE'        => true,
321
322                        'S_IMG_OPTIONS'        => $smiley_options,
323
324                        'S_ADD_ORDER_LIST_DISPLAY'        => $add_order_list . $add_order_lists[1],
325                        'S_ADD_ORDER_LIST_UNDISPLAY'    => $add_order_list . $add_order_lists[0],
326
327                        'IMG_SRC'            => $phpbb_root_path . $img_path . '/' . $default_row['smiley_url'],
328                        'IMG_PATH'            => $img_path,
329
330                        'CODE'                => $default_row['code'],
331                        'EMOTION'            => $default_row['emotion'],
332
333                        'WIDTH'                => $default_row['smiley_width'],
334                        'HEIGHT'            => $default_row['smiley_height'],
335                    ));
336                }
337
338                return;
339
340            break;
341
342            case 'create':
343            case 'modify':
344
345                if (!check_form_key($form_key))
346                {
347                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
348                }
349
350                // Get items to create/modify
351                $images = (isset($_POST['image'])) ? array_keys($request->variable('image', array('' => 0))) : array();
352
353                // Now really get the items
354                $image_id        = (isset($_POST['id'])) ? $request->variable('id', array('' => 0)) : array();
355                $image_order    = (isset($_POST['order'])) ? $request->variable('order', array('' => 0)) : array();
356                $image_width    = (isset($_POST['width'])) ? $request->variable('width', array('' => 0)) : array();
357                $image_height    = (isset($_POST['height'])) ? $request->variable('height', array('' => 0)) : array();
358                $image_add        = (isset($_POST['add_img'])) ? $request->variable('add_img', array('' => 0)) : array();
359                $image_emotion    = $request->variable('emotion', array('' => ''), true);
360                $image_code        = $request->variable('code', array('' => ''), true);
361                $image_alt        = ($request->is_set_post('alt')) ? $request->variable('alt', array('' => ''), true) : array();
362                $image_display_on_posting = (isset($_POST['display_on_posting'])) ? $request->variable('display_on_posting', array('' => 0)) : array();
363
364                // Ok, add the relevant bits if we are adding new codes to existing emoticons...
365                if ($request->variable('add_additional_code', false, false, \phpbb\request\request_interface::POST))
366                {
367                    $add_image            = $request->variable('add_image', '');
368                    $add_code            = $request->variable('add_code', '', true);
369                    $add_emotion        = $request->variable('add_emotion', '', true);
370
371                    if ($add_image && $add_emotion && $add_code)
372                    {
373                        $images[] = $add_image;
374                        $image_add[$add_image] = true;
375
376                        $image_code[$add_image] = $add_code;
377                        $image_emotion[$add_image] = $add_emotion;
378                        $image_width[$add_image] = $request->variable('add_width', 0);
379                        $image_height[$add_image] = $request->variable('add_height', 0);
380
381                        if ($request->variable('add_display_on_posting', false, false, \phpbb\request\request_interface::POST))
382                        {
383                            $image_display_on_posting[$add_image] = 1;
384                        }
385
386                        $image_order[$add_image] = $request->variable('add_order', 0);
387                    }
388                }
389
390                if ($mode == 'smilies' && $action == 'create')
391                {
392                    $smiley_count = $this->item_count($table);
393
394                    $addable_smileys_count = count($images);
395                    foreach ($images as $image)
396                    {
397                        if (!isset($image_add[$image]))
398                        {
399                            --$addable_smileys_count;
400                        }
401                    }
402
403                    if ($smiley_count + $addable_smileys_count > SMILEY_LIMIT)
404                    {
405                        trigger_error($user->lang('TOO_MANY_SMILIES', SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING);
406                    }
407                }
408
409                $icons_updated = 0;
410                $errors = array();
411                foreach ($images as $image)
412                {
413                    if ($mode == 'smilies' && ($image_emotion[$image] == '' || $image_code[$image] == ''))
414                    {
415                        $errors[$image] = 'SMILIE_NO_' . (($image_emotion[$image] == '') ? 'EMOTION' : 'CODE');
416                    }
417                    else if ($action == 'create' && !isset($image_add[$image]))
418                    {
419                        // skip images where add wasn't checked
420                    }
421                    else if (!file_exists($phpbb_root_path . $img_path . '/' . $image))
422                    {
423                        $errors[$image] = 'SMILIE_NO_FILE';
424                    }
425                    else
426                    {
427                        if ($image_width[$image] == 0 || $image_height[$image] == 0)
428                        {
429                            $img_size = getimagesize($phpbb_root_path . $img_path . '/' . $image);
430                            $image_width[$image] = $img_size[0];
431                            $image_height[$image] = $img_size[1];
432                        }
433
434                        // Adjust image width/height for icons
435                        if ($mode == 'icons')
436                        {
437                            if ($image_width[$image] > 127 && $image_width[$image] > $image_height[$image])
438                            {
439                                $image_height[$image] = (int) ($image_height[$image] * (127 / $image_width[$image]));
440                                $image_width[$image] = 127;
441                            }
442                            else if ($image_height[$image] > 127)
443                            {
444                                $image_width[$image] = (int) ($image_width[$image] * (127 / $image_height[$image]));
445                                $image_height[$image] = 127;
446                            }
447                        }
448
449                        $img_sql = array(
450                            $fields . '_url'        => $image,
451                            $fields . '_width'        => $image_width[$image],
452                            $fields . '_height'        => $image_height[$image],
453                            'display_on_posting'    => (isset($image_display_on_posting[$image])) ? 1 : 0,
454                        );
455
456                        if ($mode == 'smilies')
457                        {
458                            $img_sql = array_merge($img_sql, array(
459                                'emotion'    => $image_emotion[$image],
460                                'code'        => $image_code[$image])
461                            );
462                        }
463
464                        if ($mode == 'icons')
465                        {
466                            $img_sql = array_merge($img_sql, array(
467                                'icons_alt'    => $image_alt[$image])
468                            );
469                        }
470
471                        // Image_order holds the 'new' order value
472                        if (!empty($image_order[$image]))
473                        {
474                            $img_sql = array_merge($img_sql, array(
475                                $fields . '_order'    =>    $image_order[$image])
476                            );
477
478                            // Since we always add 'after' an item, we just need to increase all following + the current by one
479                            $sql = "UPDATE $table
480                                SET {$fields}_order = {$fields}_order + 1
481                                WHERE {$fields}_order >= {$image_order[$image]}";
482                            $db->sql_query($sql);
483
484                            // If we adjust the order, we need to adjust all other orders too - they became inaccurate...
485                            foreach ($image_order as $_image => $_order)
486                            {
487                                if ($_image == $image)
488                                {
489                                    continue;
490                                }
491
492                                if ($_order >= $image_order[$image])
493                                {
494                                    $image_order[$_image]++;
495                                }
496                            }
497                        }
498
499                        if ($action == 'modify'  && !empty($image_id[$image]))
500                        {
501                            $sql = "UPDATE $table
502                                SET " . $db->sql_build_array('UPDATE', $img_sql) . "
503                                WHERE {$fields}_id = " . $image_id[$image];
504                            $db->sql_query($sql);
505                            $icons_updated++;
506                        }
507                        else if ($action !== 'modify')
508                        {
509                            $sql = "INSERT INTO $table " . $db->sql_build_array('INSERT', $img_sql);
510                            $db->sql_query($sql);
511                            $icons_updated++;
512                        }
513
514                    }
515                }
516
517                $cache->destroy('_icons');
518                $cache->destroy('sql', $table);
519                $phpbb_container->get('text_formatter.cache')->invalidate();
520
521                $level = ($icons_updated) ? E_USER_NOTICE : E_USER_WARNING;
522                $errormsgs = '';
523                foreach ($errors as $img => $error)
524                {
525                    $errormsgs .= '<br />' . sprintf($user->lang[$error], $img);
526                }
527                if ($action == 'modify')
528                {
529                    trigger_error($user->lang($lang . '_EDITED', $icons_updated) . $errormsgs . adm_back_link($this->u_action), $level);
530                }
531                else
532                {
533                    trigger_error($user->lang($lang . '_ADDED', $icons_updated) . $errormsgs . adm_back_link($this->u_action), $level);
534                }
535
536            break;
537
538            case 'import':
539
540                $pak = $request->variable('pak', '');
541                $current = $request->variable('current', '');
542
543                if ($pak != '')
544                {
545                    $order = 0;
546
547                    if (!check_form_key($form_key))
548                    {
549                        trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
550                    }
551
552                    if (!($pak_ary = @file($phpbb_root_path . $img_path . '/' . utf8_basename($pak))))
553                    {
554                        trigger_error($user->lang['PAK_FILE_NOT_READABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
555                    }
556
557                    // Make sure the pak_ary is valid
558                    foreach ($pak_ary as $pak_entry)
559                    {
560                        if (preg_match_all("#'(.*?)', ?#", $pak_entry, $data))
561                        {
562                            if ((count($data[1]) != 4 && $mode == 'icons') ||
563                                ((count($data[1]) != 6 || (empty($data[1][4]) || empty($data[1][5]))) && $mode == 'smilies' ))
564                            {
565                                trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING);
566                            }
567                        }
568                        else
569                        {
570                            trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING);
571                        }
572                    }
573
574                    // The user has already selected a smilies_pak file
575                    if ($current == 'delete')
576                    {
577                        $db_tools = $phpbb_container->get('dbal.tools');
578                        $db_tools->sql_truncate_table($table);
579
580                        switch ($mode)
581                        {
582                            case 'smilies':
583                            break;
584
585                            case 'icons':
586                                // Reset all icon_ids
587                                $db->sql_query('UPDATE ' . TOPICS_TABLE . ' SET icon_id = 0');
588                                $db->sql_query('UPDATE ' . POSTS_TABLE . ' SET icon_id = 0');
589                            break;
590                        }
591                    }
592                    else
593                    {
594                        $cur_img = array();
595
596                        $field_sql = ($mode == 'smilies') ? 'code' : 'icons_url';
597
598                        $sql = "SELECT $field_sql
599                            FROM $table";
600                        $result = $db->sql_query($sql);
601
602                        while ($row = $db->sql_fetchrow($result))
603                        {
604                            ++$order;
605                            $cur_img[$row[$field_sql]] = 1;
606                        }
607                        $db->sql_freeresult($result);
608                    }
609
610                    if ($mode == 'smilies')
611                    {
612                        $smiley_count = $this->item_count($table);
613                        if ($smiley_count + count($pak_ary) > SMILEY_LIMIT)
614                        {
615                            trigger_error($user->lang('TOO_MANY_SMILIES', SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING);
616                        }
617                    }
618
619                    foreach ($pak_ary as $pak_entry)
620                    {
621                        $data = array();
622                        if (preg_match_all("#'(.*?)', ?#", $pak_entry, $data))
623                        {
624                            if ((count($data[1]) != 4 && $mode == 'icons') ||
625                                (count($data[1]) != 6 && $mode == 'smilies'))
626                            {
627                                trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING);
628                            }
629
630                            // Stripslash here because it got addslashed before... (on export)
631                            $img = stripslashes($data[1][0]);
632                            $width = stripslashes($data[1][1]);
633                            $height = stripslashes($data[1][2]);
634                            $display_on_posting = stripslashes($data[1][3]);
635
636                            if (isset($data[1][4]) && isset($data[1][5]))
637                            {
638                                $emotion = stripslashes($data[1][4]);
639                                $code = stripslashes($data[1][5]);
640                            }
641
642                            if ($current == 'replace' &&
643                                (($mode == 'smilies' && !empty($cur_img[$code])) ||
644                                ($mode == 'icons' && !empty($cur_img[$img]))))
645                            {
646                                $replace_sql = ($mode == 'smilies') ? $code : $img;
647                                $sql = array(
648                                    $fields . '_url'        => utf8_substr(rawurlencode($img), 0, 50),
649                                    $fields . '_height'        => (int) $height,
650                                    $fields . '_width'        => (int) $width,
651                                    'display_on_posting'    => (int) $display_on_posting,
652                                );
653
654                                if ($mode == 'smilies')
655                                {
656                                    $sql = array_merge($sql, array(
657                                        'emotion'                => $emotion,
658                                    ));
659                                }
660
661                                $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql) . "
662                                    WHERE $field_sql = '" . $db->sql_escape($replace_sql) . "'";
663                                $db->sql_query($sql);
664                            }
665                            else
666                            {
667                                ++$order;
668
669                                $sql = array(
670                                    $fields . '_url'    => utf8_substr(rawurlencode($img), 0, 50),
671                                    $fields . '_height'    => (int) $height,
672                                    $fields . '_width'    => (int) $width,
673                                    $fields . '_order'    => (int) $order,
674                                    'display_on_posting'=> (int) $display_on_posting,
675                                );
676
677                                if ($mode == 'smilies')
678                                {
679                                    $sql = array_merge($sql, array(
680                                        'code'                => $code,
681                                        'emotion'            => $emotion,
682                                    ));
683                                }
684                                $db->sql_query("INSERT INTO $table " . $db->sql_build_array('INSERT', $sql));
685                            }
686                        }
687                    }
688
689                    $cache->destroy('_icons');
690                    $cache->destroy('sql', $table);
691                    $phpbb_container->get('text_formatter.cache')->invalidate();
692
693                    trigger_error($user->lang[$lang . '_IMPORT_SUCCESS'] . adm_back_link($this->u_action));
694                }
695                else
696                {
697                    $pak_options = '';
698
699                    foreach ($_paks as $pak)
700                    {
701                        $pak_options .= '<option value="' . $pak . '">' . htmlspecialchars($pak, ENT_COMPAT) . '</option>';
702                    }
703
704                    $template->assign_vars(array(
705                        'S_CHOOSE_PAK'        => true,
706                        'S_PAK_OPTIONS'        => $pak_options,
707
708                        'L_TITLE'            => $user->lang['ACP_' . $lang],
709                        'L_EXPLAIN'            => $user->lang['ACP_' . $lang . '_EXPLAIN'],
710                        'L_NO_PAK_OPTIONS'    => $user->lang['NO_' . $lang . '_PAK'],
711                        'L_CURRENT'            => $user->lang['CURRENT_' . $lang],
712                        'L_CURRENT_EXPLAIN'    => $user->lang['CURRENT_' . $lang . '_EXPLAIN'],
713                        'L_IMPORT_SUBMIT'    => $user->lang['IMPORT_' . $lang],
714
715                        'U_BACK'        => $this->u_action,
716                        'U_ACTION'        => $this->u_action . '&amp;action=import',
717                        )
718                    );
719                }
720            break;
721
722            case 'export':
723
724                $this->page_title = 'EXPORT_' . $lang;
725                $this->tpl_name = 'message_body';
726
727                $template->assign_vars(array(
728                    'MESSAGE_TITLE'        => $user->lang['EXPORT_' . $lang],
729                    'MESSAGE_TEXT'        => sprintf($user->lang['EXPORT_' . $lang . '_EXPLAIN'], '<a href="' . $this->u_action . '&amp;action=send&amp;hash=' . generate_link_hash('acp_icons') . '">', '</a>'),
730
731                    'S_USER_NOTICE'        => true,
732                    )
733                );
734
735                return;
736
737            break;
738
739            case 'send':
740
741                if (!check_link_hash($request->variable('hash', ''), 'acp_icons'))
742                {
743                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
744                }
745
746                $sql = "SELECT *
747                    FROM $table
748                    ORDER BY {$fields}_order";
749                $result = $db->sql_query($sql);
750
751                $pak = '';
752                while ($row = $db->sql_fetchrow($result))
753                {
754                    $pak .= "'" . addslashes($row[$fields . '_url']) . "', ";
755                    $pak .= "'" . addslashes($row[$fields . '_width']) . "', ";
756                    $pak .= "'" . addslashes($row[$fields . '_height']) . "', ";
757                    $pak .= "'" . addslashes($row['display_on_posting']) . "', ";
758
759                    if ($mode == 'smilies')
760                    {
761                        $pak .= "'" . addslashes($row['emotion']) . "', ";
762                        $pak .= "'" . addslashes($row['code']) . "', ";
763                    }
764
765                    $pak .= "\n";
766                }
767                $db->sql_freeresult($result);
768
769                if ($pak != '')
770                {
771                    garbage_collection();
772
773                    header('Cache-Control: public');
774
775                    // Send out the Headers
776                    header('Content-Type: text/x-delimtext; name="' . $mode . '.pak"');
777                    header('Content-Disposition: inline; filename="' . $mode . '.pak"');
778                    echo $pak;
779
780                    flush();
781                    exit;
782                }
783                else
784                {
785                    trigger_error($user->lang['NO_' . strtoupper($fields) . '_EXPORT'] . adm_back_link($this->u_action), E_USER_WARNING);
786                }
787
788            break;
789
790            case 'delete':
791
792                if (confirm_box(true))
793                {
794                    $sql = "DELETE FROM $table
795                        WHERE {$fields}_id = $icon_id";
796                    $db->sql_query($sql);
797
798                    switch ($mode)
799                    {
800                        case 'smilies':
801                        break;
802
803                        case 'icons':
804                            // Reset appropriate icon_ids
805                            $db->sql_query('UPDATE ' . TOPICS_TABLE . "
806                                SET icon_id = 0
807                                WHERE icon_id = $icon_id");
808
809                            $db->sql_query('UPDATE ' . POSTS_TABLE . "
810                                SET icon_id = 0
811                                WHERE icon_id = $icon_id");
812                        break;
813                    }
814
815                    $notice = $user->lang[$lang . '_DELETED'];
816
817                    $cache->destroy('_icons');
818                    $cache->destroy('sql', $table);
819                    $phpbb_container->get('text_formatter.cache')->invalidate();
820
821                    if ($request->is_ajax())
822                    {
823                        $json_response = new \phpbb\json_response;
824                        $json_response->send(array(
825                            'MESSAGE_TITLE'    => $user->lang['INFORMATION'],
826                            'MESSAGE_TEXT'    => $notice,
827                            'REFRESH_DATA'    => array(
828                                'time'    => 3
829                            )
830                        ));
831                    }
832                }
833                else
834                {
835                    confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
836                        'i'            => $id,
837                        'mode'        => $mode,
838                        'id'        => $icon_id,
839                        'action'    => 'delete',
840                    )));
841                }
842
843            break;
844
845            case 'move_up':
846            case 'move_down':
847
848                if (!check_link_hash($request->variable('hash', ''), 'acp_icons'))
849                {
850                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
851                }
852
853                // Get current order id...
854                $sql = "SELECT {$fields}_order as current_order
855                    FROM $table
856                    WHERE {$fields}_id = $icon_id";
857                $result = $db->sql_query($sql);
858                $current_order = (int) $db->sql_fetchfield('current_order');
859                $db->sql_freeresult($result);
860
861                if ($current_order == 0 && $action == 'move_up')
862                {
863                    break;
864                }
865
866                // on move_down, switch position with next order_id...
867                // on move_up, switch position with previous order_id...
868                $switch_order_id = ($action == 'move_down') ? $current_order + 1 : $current_order - 1;
869
870                //
871                $sql = "UPDATE $table
872                    SET {$fields}_order = $current_order
873                    WHERE {$fields}_order = $switch_order_id
874                        AND {$fields}_id <> $icon_id";
875                $db->sql_query($sql);
876                $move_executed = (bool) $db->sql_affectedrows();
877
878                // Only update the other entry too if the previous entry got updated
879                if ($move_executed)
880                {
881                    $sql = "UPDATE $table
882                        SET {$fields}_order = $switch_order_id
883                        WHERE {$fields}_order = $current_order
884                            AND {$fields}_id = $icon_id";
885                    $db->sql_query($sql);
886                }
887
888                $cache->destroy('_icons');
889                $cache->destroy('sql', $table);
890                $phpbb_container->get('text_formatter.cache')->invalidate();
891
892                if ($request->is_ajax())
893                {
894                    $json_response = new \phpbb\json_response;
895                    $json_response->send(array(
896                        'success'    => $move_executed,
897                    ));
898                }
899
900            break;
901        }
902
903        // By default, check that image_order is valid and fix it if necessary
904        $sql = "SELECT {$fields}_id AS order_id, {$fields}_order AS fields_order
905            FROM $table
906            ORDER BY display_on_posting DESC, {$fields}_order";
907        $result = $db->sql_query($sql);
908
909        if ($row = $db->sql_fetchrow($result))
910        {
911            $order = 0;
912            do
913            {
914                ++$order;
915                if ($row['fields_order'] != $order)
916                {
917                    $db->sql_query("UPDATE $table
918                        SET {$fields}_order = $order
919                        WHERE {$fields}_id = " . $row['order_id']);
920                }
921            }
922            while ($row = $db->sql_fetchrow($result));
923        }
924        $db->sql_freeresult($result);
925
926        $template->assign_vars(array(
927            'L_TITLE'            => $user->lang['ACP_' . $lang],
928            'L_EXPLAIN'            => $user->lang['ACP_' . $lang . '_EXPLAIN'],
929            'L_IMPORT'            => $user->lang['IMPORT_' . $lang],
930            'L_EXPORT'            => $user->lang['EXPORT_' . $lang],
931            'L_NOT_DISPLAYED'    => $user->lang[$lang . '_NOT_DISPLAYED'],
932            'L_ICON_ADD'        => $user->lang['ADD_' . $lang],
933            'L_ICON_EDIT'        => $user->lang['EDIT_' . $lang],
934
935            'NOTICE'            => $notice,
936            'COLSPAN'            => ($mode == 'smilies') ? 5 : 3,
937
938            'S_SMILIES'            => ($mode == 'smilies') ? true : false,
939
940            'U_ACTION'            => $this->u_action,
941            'U_IMPORT'            => $this->u_action . '&amp;action=import',
942            'U_EXPORT'            => $this->u_action . '&amp;action=export',
943            )
944        );
945
946        /* @var $pagination \phpbb\pagination */
947        $pagination = $phpbb_container->get('pagination');
948        $pagination_start = $request->variable('start', 0);
949        $spacer = false;
950
951        $item_count = $this->item_count($table);
952
953        $sql = "SELECT *
954            FROM $table
955            ORDER BY {$fields}_order ASC";
956        $result = $db->sql_query_limit($sql, $config['smilies_per_page'], $pagination_start);
957
958        while ($row = $db->sql_fetchrow($result))
959        {
960            $alt_text = ($mode == 'smilies') ? $row['code'] : (($mode == 'icons' && !empty($row['icons_alt'])) ? $row['icons_alt'] : $row['icons_url']);
961
962            $template->assign_block_vars('items', array(
963                'S_SPACER'        => (!$spacer && !$row['display_on_posting']) ? true : false,
964                'ALT_TEXT'        => $alt_text,
965                'IMG_SRC'        => $phpbb_root_path . $img_path . '/' . $row[$fields . '_url'],
966                'WIDTH'            => $row[$fields . '_width'],
967                'HEIGHT'        => $row[$fields . '_height'],
968                'CODE'            => (isset($row['code'])) ? $row['code'] : '',
969                'EMOTION'        => (isset($row['emotion'])) ? $row['emotion'] : '',
970                'U_EDIT'        => $this->u_action . '&amp;action=edit&amp;id=' . $row[$fields . '_id'],
971                'U_DELETE'        => $this->u_action . '&amp;action=delete&amp;id=' . $row[$fields . '_id'],
972                'U_MOVE_UP'        => $this->u_action . '&amp;action=move_up&amp;id=' . $row[$fields . '_id'] . '&amp;start=' . $pagination_start . '&amp;hash=' . generate_link_hash('acp_icons'),
973                'U_MOVE_DOWN'    => $this->u_action . '&amp;action=move_down&amp;id=' . $row[$fields . '_id'] . '&amp;start=' . $pagination_start . '&amp;hash=' . generate_link_hash('acp_icons'),
974            ));
975
976            if (!$spacer && !$row['display_on_posting'])
977            {
978                $spacer = true;
979            }
980        }
981        $db->sql_freeresult($result);
982
983        $pagination->generate_template_pagination($this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start);
984    }
985
986    /**
987     * Returns the count of smilies or icons in the database
988     *
989     * @param string $table The table of items to count.
990     * @return int number of items
991     */
992    /* private */ function item_count($table)
993    {
994        global $db;
995
996        $sql = "SELECT COUNT(*) AS item_count
997            FROM $table";
998        $result = $db->sql_query($sql);
999        $item_count = (int) $db->sql_fetchfield('item_count');
1000        $db->sql_freeresult($result);
1001
1002        return $item_count;
1003    }
1004}