Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 682
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
acp_profile
0.00% covered (danger)
0.00%
0 / 680
0.00% covered (danger)
0.00%
0 / 4
31506
0.00% covered (danger)
0.00%
0 / 1
 main
0.00% covered (danger)
0.00%
0 / 438
0.00% covered (danger)
0.00%
0 / 1
10712
 build_language_options
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
650
 save_profile_field
0.00% covered (danger)
0.00%
0 / 167
0.00% covered (danger)
0.00%
0 / 1
1722
 update_insert
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
72
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
22class acp_profile
23{
24    var $u_action;
25
26    var $edit_lang_id;
27    var $lang_defs;
28
29    /**
30     * @var \phpbb\di\service_collection
31     */
32    protected $type_collection;
33
34    function main($id, $mode)
35    {
36        global $config, $db, $user, $template;
37        global $phpbb_root_path, $phpEx;
38        global $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
39
40        if (!function_exists('generate_smilies'))
41        {
42            include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
43        }
44
45        if (!function_exists('user_get_id_name'))
46        {
47            include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
48        }
49
50        $user->add_lang(array('ucp', 'acp/profile'));
51        $this->tpl_name = 'acp_profile';
52        $this->page_title = 'ACP_CUSTOM_PROFILE_FIELDS';
53
54        $field_id = $request->variable('field_id', 0);
55        $action = (isset($_POST['create'])) ? 'create' : $request->variable('action', '');
56
57        $error = array();
58
59        $form_key = 'acp_profile';
60        add_form_key($form_key);
61
62        if (!$field_id && in_array($action, array('delete','activate', 'deactivate', 'move_up', 'move_down', 'edit')))
63        {
64            trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
65        }
66
67        /* @var $cp \phpbb\profilefields\manager */
68        $cp = $phpbb_container->get('profilefields.manager');
69        $this->type_collection = $phpbb_container->get('profilefields.type_collection');
70
71        // Build Language array
72        // Based on this, we decide which elements need to be edited later and which language items are missing
73        $this->lang_defs = array();
74
75        $sql = 'SELECT lang_id, lang_iso
76            FROM ' . LANG_TABLE . '
77            ORDER BY lang_english_name';
78        $result = $db->sql_query($sql);
79
80        while ($row = $db->sql_fetchrow($result))
81        {
82            // Make some arrays with all available languages
83            $this->lang_defs['id'][$row['lang_id']] = $row['lang_iso'];
84            $this->lang_defs['iso'][$row['lang_iso']] = $row['lang_id'];
85        }
86        $db->sql_freeresult($result);
87
88        $sql = 'SELECT field_id, lang_id
89            FROM ' . PROFILE_LANG_TABLE . '
90            ORDER BY lang_id';
91        $result = $db->sql_query($sql);
92
93        while ($row = $db->sql_fetchrow($result))
94        {
95            // Which languages are available for each item
96            $this->lang_defs['entry'][$row['field_id']][] = $row['lang_id'];
97        }
98        $db->sql_freeresult($result);
99
100        // Have some fields been defined?
101        if (isset($this->lang_defs['entry']))
102        {
103            foreach ($this->lang_defs['entry'] as $field_ident => $field_ary)
104            {
105                // Fill an array with the languages that are missing for each field
106                $this->lang_defs['diff'][$field_ident] = array_diff(array_values($this->lang_defs['iso']), $field_ary);
107            }
108        }
109
110        switch ($action)
111        {
112            case 'delete':
113
114                if (confirm_box(true))
115                {
116                    $sql = 'SELECT field_ident
117                        FROM ' . PROFILE_FIELDS_TABLE . "
118                        WHERE field_id = $field_id";
119                    $result = $db->sql_query($sql);
120                    $field_ident = (string) $db->sql_fetchfield('field_ident');
121                    $db->sql_freeresult($result);
122
123                    $db->sql_transaction('begin');
124
125                    $db->sql_query('DELETE FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id");
126                    $db->sql_query('DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id");
127                    $db->sql_query('DELETE FROM ' . PROFILE_LANG_TABLE . " WHERE field_id = $field_id");
128
129                    /* @var $db_tools \phpbb\db\tools\tools_interface */
130                    $db_tools = $phpbb_container->get('dbal.tools');
131                    $db_tools->sql_column_remove(PROFILE_FIELDS_DATA_TABLE, 'pf_' . $field_ident);
132
133                    $order = 0;
134
135                    $sql = 'SELECT *
136                        FROM ' . PROFILE_FIELDS_TABLE . '
137                        ORDER BY field_order';
138                    $result = $db->sql_query($sql);
139
140                    while ($row = $db->sql_fetchrow($result))
141                    {
142                        $order++;
143                        if ($row['field_order'] != $order)
144                        {
145                            $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
146                                SET field_order = $order
147                                WHERE field_id = {$row['field_id']}";
148                            $db->sql_query($sql);
149                        }
150                    }
151                    $db->sql_freeresult($result);
152
153                    $db->sql_transaction('commit');
154
155                    $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PROFILE_FIELD_REMOVED', false, array($field_ident));
156                    trigger_error($user->lang['REMOVED_PROFILE_FIELD'] . adm_back_link($this->u_action));
157                }
158                else
159                {
160                    confirm_box(false, 'DELETE_PROFILE_FIELD', build_hidden_fields(array(
161                        'i'            => $id,
162                        'mode'        => $mode,
163                        'action'    => $action,
164                        'field_id'    => $field_id,
165                    )));
166                }
167
168            break;
169
170            case 'activate':
171
172                if (!check_link_hash($request->variable('hash', ''), 'acp_profile'))
173                {
174                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
175                }
176
177                $sql = 'SELECT lang_id
178                    FROM ' . LANG_TABLE . "
179                    WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
180                $result = $db->sql_query($sql);
181                $default_lang_id = (int) $db->sql_fetchfield('lang_id');
182                $db->sql_freeresult($result);
183
184                if (!in_array($default_lang_id, $this->lang_defs['entry'][$field_id]))
185                {
186                    trigger_error($user->lang['DEFAULT_LANGUAGE_NOT_FILLED'] . adm_back_link($this->u_action), E_USER_WARNING);
187                }
188
189                $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
190                    SET field_active = 1
191                    WHERE field_id = $field_id";
192                $db->sql_query($sql);
193
194                $sql = 'SELECT field_ident
195                    FROM ' . PROFILE_FIELDS_TABLE . "
196                    WHERE field_id = $field_id";
197                $result = $db->sql_query($sql);
198                $field_ident = (string) $db->sql_fetchfield('field_ident');
199                $db->sql_freeresult($result);
200
201                $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PROFILE_FIELD_ACTIVATE', false, array($field_ident));
202
203                if ($request->is_ajax())
204                {
205                    $json_response = new \phpbb\json_response();
206                    $json_response->send(array(
207                        'text'    => $user->lang('DEACTIVATE'),
208                    ));
209                }
210
211                trigger_error($user->lang['PROFILE_FIELD_ACTIVATED'] . adm_back_link($this->u_action));
212
213            break;
214
215            case 'deactivate':
216
217                if (!check_link_hash($request->variable('hash', ''), 'acp_profile'))
218                {
219                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
220                }
221
222                $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
223                    SET field_active = 0
224                    WHERE field_id = $field_id";
225                $db->sql_query($sql);
226
227                $sql = 'SELECT field_ident
228                    FROM ' . PROFILE_FIELDS_TABLE . "
229                    WHERE field_id = $field_id";
230                $result = $db->sql_query($sql);
231                $field_ident = (string) $db->sql_fetchfield('field_ident');
232                $db->sql_freeresult($result);
233
234                if ($request->is_ajax())
235                {
236                    $json_response = new \phpbb\json_response();
237                    $json_response->send(array(
238                        'text'    => $user->lang('ACTIVATE'),
239                    ));
240                }
241
242                $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PROFILE_FIELD_DEACTIVATE', false, array($field_ident));
243
244                trigger_error($user->lang['PROFILE_FIELD_DEACTIVATED'] . adm_back_link($this->u_action));
245
246            break;
247
248            case 'move_up':
249            case 'move_down':
250
251                if (!check_link_hash($request->variable('hash', ''), 'acp_profile'))
252                {
253                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
254                }
255
256                $sql = 'SELECT field_order
257                    FROM ' . PROFILE_FIELDS_TABLE . "
258                    WHERE field_id = $field_id";
259                $result = $db->sql_query($sql);
260                $field_order = $db->sql_fetchfield('field_order');
261                $db->sql_freeresult($result);
262
263                if ($field_order === false || ($field_order == 0 && $action == 'move_up'))
264                {
265                    break;
266                }
267                $field_order = (int) $field_order;
268                $order_total = $field_order * 2 + (($action == 'move_up') ? -1 : 1);
269
270                $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
271                    SET field_order = $order_total - field_order
272                    WHERE field_order IN ($field_order" . (($action == 'move_up') ? $field_order - 1 : $field_order + 1) . ')';
273                $db->sql_query($sql);
274
275                if ($request->is_ajax())
276                {
277                    $json_response = new \phpbb\json_response;
278                    $json_response->send(array(
279                        'success'    => (bool) $db->sql_affectedrows(),
280                    ));
281                }
282
283            break;
284
285            case 'create':
286            case 'edit':
287
288                $step = $request->variable('step', 1);
289
290                $submit = (isset($_REQUEST['next']) || isset($_REQUEST['prev'])) ? true : false;
291                $save = (isset($_REQUEST['save'])) ? true : false;
292
293                // The language id of default language
294                $this->edit_lang_id = $this->lang_defs['iso'][$config['default_lang']];
295
296                // We are editing... we need to grab basic things
297                if ($action == 'edit')
298                {
299                    $sql = 'SELECT l.*, f.*
300                        FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f
301                        WHERE l.lang_id = ' . $this->edit_lang_id . "
302                            AND f.field_id = $field_id
303                            AND l.field_id = f.field_id";
304                    $result = $db->sql_query($sql);
305                    $field_row = $db->sql_fetchrow($result);
306                    $db->sql_freeresult($result);
307
308                    if (!$field_row)
309                    {
310                        // Some admin changed the default language?
311                        $sql = 'SELECT l.*, f.*
312                            FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f
313                            WHERE l.lang_id <> ' . $this->edit_lang_id . "
314                            AND f.field_id = $field_id
315                            AND l.field_id = f.field_id";
316                        $result = $db->sql_query($sql);
317                        $field_row = $db->sql_fetchrow($result);
318                        $db->sql_freeresult($result);
319
320                        if (!$field_row)
321                        {
322                            trigger_error($user->lang['FIELD_NOT_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING);
323                        }
324
325                        $this->edit_lang_id = $field_row['lang_id'];
326                    }
327                    $field_type = $field_row['field_type'];
328                    $profile_field = $this->type_collection[$field_type];
329
330                    // Get language entries
331                    $sql = 'SELECT *
332                        FROM ' . PROFILE_FIELDS_LANG_TABLE . '
333                        WHERE lang_id = ' . $this->edit_lang_id . "
334                            AND field_id = $field_id
335                        ORDER BY option_id ASC";
336                    $result = $db->sql_query($sql);
337
338                    $lang_options = array();
339                    while ($row = $db->sql_fetchrow($result))
340                    {
341                        $lang_options[$row['option_id']] = $row['lang_value'];
342                    }
343                    $db->sql_freeresult($result);
344
345                    $s_hidden_fields = '<input type="hidden" name="field_id" value="' . $field_id . '" />';
346                }
347                else // action = create
348                {
349                    // We are adding a new field, define basic params
350                    $lang_options = array();
351
352                    $field_type = $request->variable('field_type', '');
353
354                    if (!isset($this->type_collection[$field_type]))
355                    {
356                        trigger_error($user->lang['NO_FIELD_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING);
357                    }
358
359                    $profile_field = $this->type_collection[$field_type];
360                    $field_row = array_merge($profile_field->get_default_option_values(), array(
361                        'field_ident'        => str_replace(' ', '_', utf8_clean_string($request->variable('field_ident', '', true))),
362                        'field_required'    => 0,
363                        'field_show_novalue'=> 0,
364                        'field_hide'        => 0,
365                        'field_show_profile'=> 0,
366                        'field_no_view'        => 0,
367                        'field_show_on_reg'    => 0,
368                        'field_show_on_pm'    => 0,
369                        'field_show_on_vt'    => 0,
370                        'field_show_on_ml'    => 0,
371                        'field_is_contact'    => 0,
372                        'field_contact_desc'=> '',
373                        'field_contact_url'    => '',
374                        'lang_name'            => $request->variable('field_ident', '', true),
375                        'lang_explain'        => '',
376                        'lang_default_value'=> '')
377                    );
378
379                    $s_hidden_fields = '<input type="hidden" name="field_type" value="' . $field_type . '" />';
380                }
381
382                // $exclude contains the data we gather in each step
383                $exclude = array(
384                    1    => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_show_on_ml', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view', 'field_is_contact', 'field_contact_desc', 'field_contact_url'),
385                    2    => array('field_length', 'field_maxlen', 'field_minlen', 'field_validation', 'field_novalue', 'field_default_value'),
386                    3    => array('l_lang_name', 'l_lang_explain', 'l_lang_default_value', 'l_lang_options')
387                );
388
389                // Visibility Options...
390                $visibility_ary = array(
391                    'field_required',
392                    'field_show_novalue',
393                    'field_show_on_reg',
394                    'field_show_on_pm',
395                    'field_show_on_vt',
396                    'field_show_on_ml',
397                    'field_show_profile',
398                    'field_hide',
399                    'field_is_contact',
400                );
401
402                /**
403                * Event to add initialization for new profile field table fields
404                *
405                * @event core.acp_profile_create_edit_init
406                * @var    string    action            create|edit
407                * @var    int        step            Configuration step (1|2|3)
408                * @var    bool    submit            Form has been submitted
409                * @var    bool    save            Configuration should be saved
410                * @var    string    field_type        Type of the field we are dealing with
411                * @var    array    field_row        Array of data about the field
412                * @var    array    exclude            Array of excluded fields by step
413                * @var    array    visibility_ary    Array of fields that are visibility related
414                * @since 3.1.6-RC1
415                */
416                $vars = array(
417                    'action',
418                    'step',
419                    'submit',
420                    'save',
421                    'field_type',
422                    'field_row',
423                    'exclude',
424                    'visibility_ary',
425                );
426                extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_init', compact($vars)));
427
428                $options = $profile_field->prepare_options_form($exclude, $visibility_ary);
429
430                $cp->vars['field_ident']        = ($action == 'create' && $step == 1) ? utf8_clean_string($request->variable('field_ident', $field_row['field_ident'], true)) : $request->variable('field_ident', $field_row['field_ident']);
431                $cp->vars['lang_name']            = $request->variable('lang_name', $field_row['lang_name'], true);
432                $cp->vars['lang_explain']        = $request->variable('lang_explain', $field_row['lang_explain'], true);
433                $cp->vars['lang_default_value']    = $request->variable('lang_default_value', $field_row['lang_default_value'], true);
434                $cp->vars['field_contact_desc']    = $request->variable('field_contact_desc', $field_row['field_contact_desc'], true);
435                $cp->vars['field_contact_url']    = $request->variable('field_contact_url', $field_row['field_contact_url'], true);
436
437                foreach ($visibility_ary as $val)
438                {
439                    $cp->vars[$val] = ($submit || $save) ? $request->variable($val, 0) : $field_row[$val];
440                }
441
442                $cp->vars['field_no_view'] = $request->variable('field_no_view', (int) $field_row['field_no_view']);
443
444                // If the user has submitted a form with options (i.e. dropdown field)
445                if ($options)
446                {
447                    $exploded_options = (is_array($options)) ? $options : explode("\n", $options);
448
449                    if (count($exploded_options) == count($lang_options) || $action == 'create')
450                    {
451                        // The number of options in the field is equal to the number of options already in the database
452                        // Or we are creating a new dropdown list.
453                        $cp->vars['lang_options'] = $exploded_options;
454                    }
455                    else if ($action == 'edit')
456                    {
457                        // Changing the number of options? (We remove and re-create the option fields)
458                        $cp->vars['lang_options'] = $exploded_options;
459                    }
460                }
461                else
462                {
463                    $cp->vars['lang_options'] = $lang_options;
464                }
465
466                // step 2
467                foreach ($exclude[2] as $key)
468                {
469                    $var = $request->variable($key, $field_row[$key], true);
470
471                    $field_data = $cp->vars;
472                    $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 2);
473                    $cp->vars = $field_data;
474
475                    $cp->vars[$key] = $var;
476                }
477
478                foreach ($exclude[3] as $key)
479                {
480                    $cp->vars[$key] = $request->variable($key, array(0 => ''), true);
481
482                    if (!$cp->vars[$key] && $action == 'edit')
483                    {
484                        $cp->vars[$key] = ${$key};
485                    }
486
487                    $field_data = $cp->vars;
488                    $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 3);
489                    $cp->vars = $field_data;
490                }
491
492                // Check for general issues in every step
493                if ($submit) //  && $step == 1
494                {
495                    // Check values for step 1
496                    if ($cp->vars['field_ident'] == '')
497                    {
498                        $error[] = $user->lang['EMPTY_FIELD_IDENT'];
499                    }
500
501                    if (!preg_match('/^[a-z_]+$/', $cp->vars['field_ident']))
502                    {
503                        $error[] = $user->lang['INVALID_CHARS_FIELD_IDENT'];
504                    }
505
506                    if (strlen($cp->vars['field_ident']) > 17)
507                    {
508                        $error[] = $user->lang['INVALID_FIELD_IDENT_LEN'];
509                    }
510
511                    if ($cp->vars['lang_name'] == '')
512                    {
513                        $error[] = $user->lang['EMPTY_USER_FIELD_NAME'];
514                    }
515
516                    $error = $profile_field->validate_options_on_submit($error, $cp->vars);
517
518                    // Check for already existing field ident
519                    if ($action != 'edit')
520                    {
521                        $sql = 'SELECT field_ident
522                            FROM ' . PROFILE_FIELDS_TABLE . "
523                            WHERE field_ident = '" . $db->sql_escape($cp->vars['field_ident']) . "'";
524                        $result = $db->sql_query($sql);
525                        $row = $db->sql_fetchrow($result);
526                        $db->sql_freeresult($result);
527
528                        if ($row)
529                        {
530                            $error[] = $user->lang['FIELD_IDENT_ALREADY_EXIST'];
531                        }
532                    }
533                }
534
535                if (count($error))
536                {
537                    $submit = false;
538                }
539                else
540                {
541                    $step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step);
542                }
543
544                // Build up the specific hidden fields
545                foreach ($exclude as $num => $key_ary)
546                {
547                    if ($num == $step)
548                    {
549                        continue;
550                    }
551
552                    $_new_key_ary = array();
553
554                    $field_data = $cp->vars;
555                    foreach ($key_ary as $key)
556                    {
557                        $var = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data);
558                        if ($var !== null)
559                        {
560                            $_new_key_ary[$key] = $var;
561                        }
562                    }
563                    $cp->vars = $field_data;
564
565                    $s_hidden_fields .= build_hidden_fields($_new_key_ary);
566                }
567
568                if (!count($error))
569                {
570                    if (($step == 3 && (count($this->lang_defs['iso']) == 1 || $save)) || ($action == 'edit' && $save))
571                    {
572                        if (!check_form_key($form_key))
573                        {
574                            trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
575                        }
576
577                        $this->save_profile_field($cp, $field_type, $action);
578                    }
579                }
580
581                $template->assign_vars(array(
582                    'S_EDIT'            => true,
583                    'S_EDIT_MODE'        => ($action == 'edit') ? true : false,
584                    'ERROR_MSG'            => (count($error)) ? implode('<br />', $error) : '',
585
586                    'L_TITLE'            => $user->lang['STEP_' . $step . '_TITLE_' . strtoupper($action)],
587                    'L_EXPLAIN'            => $user->lang['STEP_' . $step . '_EXPLAIN_' . strtoupper($action)],
588
589                    'U_ACTION'            => $this->u_action . "&amp;action=$action&amp;step=$step",
590                    'U_BACK'            => $this->u_action)
591                );
592
593                // Now go through the steps
594                switch ($step)
595                {
596                    // Create basic options - only small differences between field types
597                    case 1:
598                        $template_vars = array(
599                            'S_STEP_ONE'        => true,
600                            'S_FIELD_REQUIRED'    => ($cp->vars['field_required']) ? true : false,
601                            'S_FIELD_SHOW_NOVALUE'=> ($cp->vars['field_show_novalue']) ? true : false,
602                            'S_SHOW_ON_REG'        => ($cp->vars['field_show_on_reg']) ? true : false,
603                            'S_SHOW_ON_PM'        => ($cp->vars['field_show_on_pm']) ? true : false,
604                            'S_SHOW_ON_VT'        => ($cp->vars['field_show_on_vt']) ? true : false,
605                            'S_SHOW_ON_MEMBERLIST'=> ($cp->vars['field_show_on_ml']) ? true : false,
606                            'S_FIELD_HIDE'        => ($cp->vars['field_hide']) ? true : false,
607                            'S_SHOW_PROFILE'    => ($cp->vars['field_show_profile']) ? true : false,
608                            'S_FIELD_NO_VIEW'    => ($cp->vars['field_no_view']) ? true : false,
609                            'S_FIELD_CONTACT'    => $cp->vars['field_is_contact'],
610                            'FIELD_CONTACT_DESC'=> $cp->vars['field_contact_desc'],
611                            'FIELD_CONTACT_URL'    => $cp->vars['field_contact_url'],
612
613                            'L_LANG_SPECIFIC'    => sprintf($user->lang['LANG_SPECIFIC_OPTIONS'], $config['default_lang']),
614                            'FIELD_TYPE'        => $profile_field->get_name(),
615                            'FIELD_IDENT'        => $cp->vars['field_ident'],
616                            'LANG_NAME'            => $cp->vars['lang_name'],
617                            'LANG_EXPLAIN'        => $cp->vars['lang_explain'],
618                        );
619
620                        $field_data = $cp->vars;
621                        $profile_field->display_options($template_vars, $field_data);
622                        $cp->vars = $field_data;
623
624                        // Build common create options
625                        $template->assign_vars($template_vars);
626                    break;
627
628                    case 2:
629
630                        $template->assign_vars(array(
631                            'S_STEP_TWO'        => true,
632                            'L_NEXT_STEP'            => (count($this->lang_defs['iso']) == 1) ? $user->lang['SAVE'] : $user->lang['PROFILE_LANG_OPTIONS'])
633                        );
634
635                        // Build options based on profile type
636                        $options = $profile_field->get_options($this->lang_defs['iso'][$config['default_lang']], $cp->vars);
637
638                        foreach ($options as $option_ary)
639                        {
640                            $template->assign_block_vars('option', $option_ary);
641                        }
642
643                    break;
644
645                    // Define remaining language variables
646                    case 3:
647
648                        $template->assign_var('S_STEP_THREE', true);
649                        $options = $this->build_language_options($cp, $field_type, $action);
650
651                        foreach ($options as $lang_id => $lang_ary)
652                        {
653                            $template->assign_block_vars('options', array(
654                                'LANGUAGE'        => sprintf($user->lang[(($lang_id == $this->edit_lang_id) ? 'DEFAULT_' : '') . 'ISO_LANGUAGE'], $lang_ary['lang_iso']))
655                            );
656
657                            foreach ($lang_ary['fields'] as $field_ident => $field_ary)
658                            {
659                                $template->assign_block_vars('options.field', array(
660                                    'L_TITLE'        => $field_ary['TITLE'],
661                                    'L_EXPLAIN'        => (isset($field_ary['EXPLAIN'])) ? $field_ary['EXPLAIN'] : '',
662                                    'FIELD'            => $field_ary['FIELD'])
663                                );
664                            }
665                        }
666
667                    break;
668                }
669
670                $field_data = $cp->vars;
671                /**
672                * Event to add template variables for new profile field table fields
673                *
674                * @event core.acp_profile_create_edit_after
675                * @var    string    action            create|edit
676                * @var    int        step            Configuration step (1|2|3)
677                * @var    bool    submit            Form has been submitted
678                * @var    bool    save            Configuration should be saved
679                * @var    string    field_type        Type of the field we are dealing with
680                * @var    array    field_data        Array of data about the field
681                * @var    array    s_hidden_fields    Array of hidden fields in case this needs modification
682                * @var    array    options            Array of options specific to this step
683                * @since 3.1.6-RC1
684                */
685                $vars = array(
686                    'action',
687                    'step',
688                    'submit',
689                    'save',
690                    'field_type',
691                    'field_data',
692                    's_hidden_fields',
693                    'options',
694                );
695                extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_after', compact($vars)));
696
697                $template->assign_vars(array(
698                    'S_HIDDEN_FIELDS'    => $s_hidden_fields)
699                );
700
701                return;
702
703            break;
704        }
705
706        $tpl_name = $this->tpl_name;
707        $page_title = $this->page_title;
708        $u_action = $this->u_action;
709
710        /**
711        * Event to handle actions on the ACP profile fields page
712        *
713        * @event core.acp_profile_action
714        * @var    string    action        Action that is being performed
715        * @var    string    tpl_name    Template file to load
716        * @var    string    page_title    Page title
717        * @var    string    u_action    The URL we are at, read only
718        * @since 3.2.2-RC1
719        */
720        $vars = array(
721            'action',
722            'tpl_name',
723            'page_title',
724            'u_action',
725        );
726        extract($phpbb_dispatcher->trigger_event('core.acp_profile_action', compact($vars)));
727
728        $this->tpl_name = $tpl_name;
729        $this->page_title = $page_title;
730        unset($u_action);
731
732        $sql = 'SELECT *
733            FROM ' . PROFILE_FIELDS_TABLE . '
734            ORDER BY field_order';
735        $result = $db->sql_query($sql);
736
737        $s_one_need_edit = false;
738        while ($row = $db->sql_fetchrow($result))
739        {
740            $active_lang = (!$row['field_active']) ? 'ACTIVATE' : 'DEACTIVATE';
741            $active_value = (!$row['field_active']) ? 'activate' : 'deactivate';
742            $id = $row['field_id'];
743
744            $s_need_edit = (count($this->lang_defs['diff'][$row['field_id']])) ? true : false;
745
746            if ($s_need_edit)
747            {
748                $s_one_need_edit = true;
749            }
750
751            if (!isset($this->type_collection[$row['field_type']]))
752            {
753                continue;
754            }
755            $profile_field = $this->type_collection[$row['field_type']];
756
757            $field_block = array(
758                'FIELD_IDENT'        => $row['field_ident'],
759                'FIELD_TYPE'        => $profile_field->get_name(),
760
761                'L_ACTIVATE_DEACTIVATE'        => $user->lang[$active_lang],
762                'U_ACTIVATE_DEACTIVATE'        => $this->u_action . "&amp;action=$active_value&amp;field_id=$id" . '&amp;hash=' . generate_link_hash('acp_profile'),
763                'U_EDIT'                    => $this->u_action . "&amp;action=edit&amp;field_id=$id",
764                'U_TRANSLATE'                => $this->u_action . "&amp;action=edit&amp;field_id=$id&amp;step=3",
765                'U_DELETE'                    => $this->u_action . "&amp;action=delete&amp;field_id=$id",
766                'U_MOVE_UP'                    => $this->u_action . "&amp;action=move_up&amp;field_id=$id" . '&amp;hash=' . generate_link_hash('acp_profile'),
767                'U_MOVE_DOWN'                => $this->u_action . "&amp;action=move_down&amp;field_id=$id" . '&amp;hash=' . generate_link_hash('acp_profile'),
768
769                'S_NEED_EDIT'                => $s_need_edit,
770            );
771
772            /**
773            * Event to modify profile field data before it is assigned to the template
774            *
775            * @event core.acp_profile_modify_profile_row
776            * @var    array    row                Array with data for the current profile field
777            * @var    array    field_block        Template data that is being assigned to the 'fields' block
778            * @var    object    profile_field    A profile field instance, implements \phpbb\profilefields\type\type_base
779            * @since 3.2.2-RC1
780            */
781            $vars = array(
782                'row',
783                'field_block',
784                'profile_field',
785            );
786            extract($phpbb_dispatcher->trigger_event('core.acp_profile_modify_profile_row', compact($vars)));
787
788            $template->assign_block_vars('fields', $field_block);
789        }
790        $db->sql_freeresult($result);
791
792        // At least one option field needs editing?
793        if ($s_one_need_edit)
794        {
795            $template->assign_var('S_NEED_EDIT', true);
796        }
797
798        $s_select_type = '';
799        foreach ($this->type_collection as $key => $profile_field)
800        {
801            $s_select_type .= '<option value="' . $key . '">' . $profile_field->get_name() . '</option>';
802        }
803
804        $template->assign_vars(array(
805            'U_ACTION'            => $this->u_action,
806            'S_TYPE_OPTIONS'    => $s_select_type,
807        ));
808    }
809
810    /**
811    * Build all Language specific options
812    */
813    function build_language_options($cp, $field_type, $action = 'create')
814    {
815        global $user, $config, $db, $request;
816
817        $default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']];
818
819        $sql = 'SELECT lang_id, lang_iso
820            FROM ' . LANG_TABLE . '
821            WHERE lang_id <> ' . (int) $default_lang_id . '
822            ORDER BY lang_english_name';
823        $result = $db->sql_query($sql);
824
825        $languages = array();
826        while ($row = $db->sql_fetchrow($result))
827        {
828            $languages[$row['lang_id']] = $row['lang_iso'];
829        }
830        $db->sql_freeresult($result);
831
832        $profile_field = $this->type_collection[$field_type];
833        $options = $profile_field->get_language_options($cp->vars);
834
835        $lang_options = array();
836
837        foreach ($options as $field => $field_type)
838        {
839            $lang_options[1]['lang_iso'] = $this->lang_defs['id'][$default_lang_id];
840            $lang_options[1]['fields'][$field] = array(
841                'TITLE'        => $user->lang['CP_' . strtoupper($field)],
842                'FIELD'        => '<dd>' . ((is_array($cp->vars[$field])) ? implode('<br />', $cp->vars[$field]) : bbcode_nl2br($cp->vars[$field])) . '</dd>'
843            );
844
845            if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN']))
846            {
847                $lang_options[1]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN'];
848            }
849        }
850
851        foreach ($languages as $lang_id => $lang_iso)
852        {
853            $lang_options[$lang_id]['lang_iso'] = $lang_iso;
854            foreach ($options as $field => $field_type)
855            {
856                $value = ($action == 'create') ? $request->variable('l_' . $field, array(0 => ''), true) : $cp->vars['l_' . $field];
857                if ($field == 'lang_options')
858                {
859                    $var = (!isset($cp->vars['l_lang_options'][$lang_id]) || !is_array($cp->vars['l_lang_options'][$lang_id])) ? $cp->vars['lang_options'] : $cp->vars['l_lang_options'][$lang_id];
860
861                    switch ($field_type)
862                    {
863                        case 'two_options':
864
865                            $lang_options[$lang_id]['fields'][$field] = array(
866                                'TITLE'        => $user->lang['CP_' . strtoupper($field)],
867                                'FIELD'        => '
868                                            <dd><input class="medium" name="l_' . $field . '[' . $lang_id . '][]" value="' . ((isset($value[$lang_id][0])) ? $value[$lang_id][0] : $var[0]) . '" /> ' . $user->lang['FIRST_OPTION'] . '</dd>
869                                            <dd><input class="medium" name="l_' . $field . '[' . $lang_id . '][]" value="' . ((isset($value[$lang_id][1])) ? $value[$lang_id][1] : $var[1]) . '" /> ' . $user->lang['SECOND_OPTION'] . '</dd>'
870                            );
871                        break;
872
873                        case 'optionfield':
874                            $value = ((isset($value[$lang_id])) ? ((is_array($value[$lang_id])) ?  implode("\n", $value[$lang_id]) : $value[$lang_id]) : implode("\n", $var));
875                            $lang_options[$lang_id]['fields'][$field] = array(
876                                'TITLE'        => $user->lang['CP_' . strtoupper($field)],
877                                'FIELD'        => '<dd><textarea name="l_' . $field . '[' . $lang_id . ']" rows="7" cols="80">' . $value . '</textarea></dd>'
878                            );
879                        break;
880                    }
881
882                    if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN']))
883                    {
884                        $lang_options[$lang_id]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN'];
885                    }
886                }
887                else
888                {
889                    $var = ($action == 'create' || !is_array($cp->vars[$field])) ? $cp->vars[$field] : $cp->vars[$field][$lang_id];
890
891                    $lang_options[$lang_id]['fields'][$field] = array(
892                        'TITLE'        => $user->lang['CP_' . strtoupper($field)],
893                        'FIELD'        => ($field_type == 'string') ? '<dd><input class="medium" type="text" name="l_' . $field . '[' . $lang_id . ']" value="' . ((isset($value[$lang_id])) ? $value[$lang_id] : $var) . '" /></dd>' : '<dd><textarea name="l_' . $field . '[' . $lang_id . ']" rows="3" cols="80">' . ((isset($value[$lang_id])) ? $value[$lang_id] : $var) . '</textarea></dd>'
894                    );
895
896                    if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN']))
897                    {
898                        $lang_options[$lang_id]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN'];
899                    }
900                }
901            }
902        }
903
904        return $lang_options;
905    }
906
907    /**
908    * Save Profile Field
909    */
910    function save_profile_field($cp, $field_type, $action = 'create')
911    {
912        global $db, $config, $user, $phpbb_container, $phpbb_log, $request, $phpbb_dispatcher;
913
914        $field_id = $request->variable('field_id', 0);
915
916        // Collect all information, if something is going wrong, abort the operation
917        $profile_sql = $profile_lang = $empty_lang = $profile_lang_fields = array();
918
919        $default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']];
920
921        if ($action == 'create')
922        {
923            $sql = 'SELECT MAX(field_order) as max_field_order
924                FROM ' . PROFILE_FIELDS_TABLE;
925            $result = $db->sql_query($sql);
926            $new_field_order = (int) $db->sql_fetchfield('max_field_order');
927            $db->sql_freeresult($result);
928
929            $field_ident = $cp->vars['field_ident'];
930        }
931
932        // Save the field
933        $profile_fields = array(
934            'field_length'            => $cp->vars['field_length'],
935            'field_minlen'            => $cp->vars['field_minlen'],
936            'field_maxlen'            => $cp->vars['field_maxlen'],
937            'field_novalue'            => $cp->vars['field_novalue'],
938            'field_default_value'    => $cp->vars['field_default_value'],
939            'field_validation'        => $cp->vars['field_validation'],
940            'field_required'        => $cp->vars['field_required'],
941            'field_show_novalue'    => $cp->vars['field_show_novalue'],
942            'field_show_on_reg'        => $cp->vars['field_show_on_reg'],
943            'field_show_on_pm'        => $cp->vars['field_show_on_pm'],
944            'field_show_on_vt'        => $cp->vars['field_show_on_vt'],
945            'field_show_on_ml'        => $cp->vars['field_show_on_ml'],
946            'field_hide'            => $cp->vars['field_hide'],
947            'field_show_profile'    => $cp->vars['field_show_profile'],
948            'field_no_view'            => $cp->vars['field_no_view'],
949            'field_is_contact'        => $cp->vars['field_is_contact'],
950            'field_contact_desc'    => $cp->vars['field_contact_desc'],
951            'field_contact_url'        => $cp->vars['field_contact_url'],
952        );
953
954        $field_data = $cp->vars;
955        /**
956        * Event to modify profile field configuration data before saving to database
957        *
958        * @event core.acp_profile_create_edit_save_before
959        * @var    string    action            create|edit
960        * @var    string    field_type        Type of the field we are dealing with
961        * @var    array    field_data        Array of data about the field
962        * @var    array    profile_fields    Array of fields to be sent to the database
963        * @since 3.1.6-RC1
964        */
965        $vars = array(
966            'action',
967            'field_type',
968            'field_data',
969            'profile_fields',
970        );
971        extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_save_before', compact($vars)));
972
973        if ($action == 'create')
974        {
975            $profile_fields += array(
976                'field_type'        => $field_type,
977                'field_ident'        => $field_ident,
978                'field_name'        => $field_ident,
979                'field_order'        => $new_field_order + 1,
980                'field_active'        => 1
981            );
982
983            $sql = 'INSERT INTO ' . PROFILE_FIELDS_TABLE . ' ' . $db->sql_build_array('INSERT', $profile_fields);
984            $db->sql_query($sql);
985
986            $field_id = $db->sql_nextid();
987        }
988        else
989        {
990            $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . '
991                SET ' . $db->sql_build_array('UPDATE', $profile_fields) . "
992                WHERE field_id = $field_id";
993            $db->sql_query($sql);
994        }
995
996        $profile_field = $this->type_collection[$field_type];
997
998        if ($action == 'create')
999        {
1000            $field_ident = 'pf_' . $field_ident;
1001            /* @var $db_tools \phpbb\db\tools\tools_interface */
1002            $db_tools = $phpbb_container->get('dbal.tools');
1003            $db_tools->sql_column_add(PROFILE_FIELDS_DATA_TABLE, $field_ident, array($profile_field->get_database_column_type(), null));
1004        }
1005
1006        $sql_ary = array(
1007            'lang_name'                => $cp->vars['lang_name'],
1008            'lang_explain'            => $cp->vars['lang_explain'],
1009            'lang_default_value'    => $cp->vars['lang_default_value']
1010        );
1011
1012        if ($action == 'create')
1013        {
1014            $sql_ary['field_id'] = $field_id;
1015            $sql_ary['lang_id'] = $default_lang_id;
1016
1017            $profile_sql[] = 'INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
1018        }
1019        else
1020        {
1021            $this->update_insert(PROFILE_LANG_TABLE, $sql_ary, array('field_id' => $field_id, 'lang_id' => $default_lang_id));
1022        }
1023
1024        if (is_array($cp->vars['l_lang_name']) && count($cp->vars['l_lang_name']))
1025        {
1026            foreach ($cp->vars['l_lang_name'] as $lang_id => $data)
1027            {
1028                if (($cp->vars['lang_name'] != '' && $cp->vars['l_lang_name'][$lang_id] == '')
1029                    || ($cp->vars['lang_explain'] != '' && $cp->vars['l_lang_explain'][$lang_id] == '')
1030                    || ($cp->vars['lang_default_value'] != '' && $cp->vars['l_lang_default_value'][$lang_id] == ''))
1031                {
1032                    $empty_lang[$lang_id] = true;
1033                    break;
1034                }
1035
1036                if (!isset($empty_lang[$lang_id]))
1037                {
1038                    $profile_lang[] = array(
1039                        'field_id'        => $field_id,
1040                        'lang_id'        => $lang_id,
1041                        'lang_name'        => $cp->vars['l_lang_name'][$lang_id],
1042                        'lang_explain'    => (isset($cp->vars['l_lang_explain'][$lang_id])) ? $cp->vars['l_lang_explain'][$lang_id] : '',
1043                        'lang_default_value'    => (isset($cp->vars['l_lang_default_value'][$lang_id])) ? $cp->vars['l_lang_default_value'][$lang_id] : ''
1044                    );
1045                }
1046            }
1047
1048            foreach ($empty_lang as $lang_id => $NULL)
1049            {
1050                $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . "
1051                    WHERE field_id = $field_id
1052                    AND lang_id = " . (int) $lang_id;
1053                $db->sql_query($sql);
1054            }
1055        }
1056
1057        $cp->vars = $profile_field->get_language_options_input($cp->vars);
1058
1059        if ($cp->vars['lang_options'])
1060        {
1061            if (!is_array($cp->vars['lang_options']))
1062            {
1063                $cp->vars['lang_options'] = explode("\n", $cp->vars['lang_options']);
1064            }
1065
1066            if ($action != 'create')
1067            {
1068                $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . "
1069                    WHERE field_id = $field_id
1070                        AND lang_id = " . (int) $default_lang_id;
1071                $db->sql_query($sql);
1072            }
1073
1074            foreach ($cp->vars['lang_options'] as $option_id => $value)
1075            {
1076                $sql_ary = array(
1077                    'field_type'    => $field_type,
1078                    'lang_value'    => $value
1079                );
1080
1081                if ($action == 'create')
1082                {
1083                    $sql_ary['field_id'] = $field_id;
1084                    $sql_ary['lang_id'] = $default_lang_id;
1085                    $sql_ary['option_id'] = (int) $option_id;
1086
1087                    $profile_sql[] = 'INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
1088                }
1089                else
1090                {
1091                    $this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql_ary, array(
1092                        'field_id'    => $field_id,
1093                        'lang_id'    => (int) $default_lang_id,
1094                        'option_id'    => (int) $option_id)
1095                    );
1096                }
1097            }
1098        }
1099
1100        if (is_array($cp->vars['l_lang_options']) && count($cp->vars['l_lang_options']))
1101        {
1102            $empty_lang = array();
1103
1104            foreach ($cp->vars['l_lang_options'] as $lang_id => $lang_ary)
1105            {
1106                if (!is_array($lang_ary))
1107                {
1108                    $lang_ary = explode("\n", $lang_ary);
1109                }
1110
1111                if (count($lang_ary) != count($cp->vars['lang_options']))
1112                {
1113                    $empty_lang[$lang_id] = true;
1114                }
1115
1116                if (!isset($empty_lang[$lang_id]))
1117                {
1118                    if ($action != 'create')
1119                    {
1120                        $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . "
1121                            WHERE field_id = $field_id
1122                            AND lang_id = " . (int) $lang_id;
1123                        $db->sql_query($sql);
1124                    }
1125
1126                    foreach ($lang_ary as $option_id => $value)
1127                    {
1128                        $profile_lang_fields[] = array(
1129                            'field_id'        => (int) $field_id,
1130                            'lang_id'        => (int) $lang_id,
1131                            'option_id'        => (int) $option_id,
1132                            'field_type'    => $field_type,
1133                            'lang_value'    => $value
1134                        );
1135                    }
1136                }
1137            }
1138
1139            foreach ($empty_lang as $lang_id => $NULL)
1140            {
1141                $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . "
1142                    WHERE field_id = $field_id
1143                    AND lang_id = " . (int) $lang_id;
1144                $db->sql_query($sql);
1145            }
1146        }
1147
1148        foreach ($profile_lang as $sql)
1149        {
1150            if ($action == 'create')
1151            {
1152                $profile_sql[] = 'INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql);
1153            }
1154            else
1155            {
1156                $lang_id = $sql['lang_id'];
1157                unset($sql['lang_id'], $sql['field_id']);
1158
1159                $this->update_insert(PROFILE_LANG_TABLE, $sql, array('lang_id' => (int) $lang_id, 'field_id' => $field_id));
1160            }
1161        }
1162
1163        if (count($profile_lang_fields))
1164        {
1165            foreach ($profile_lang_fields as $sql)
1166            {
1167                if ($action == 'create')
1168                {
1169                    $profile_sql[] = 'INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql);
1170                }
1171                else
1172                {
1173                    $lang_id = $sql['lang_id'];
1174                    $option_id = $sql['option_id'];
1175                    unset($sql['lang_id'], $sql['field_id'], $sql['option_id']);
1176
1177                    $this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql, array(
1178                        'lang_id'    => $lang_id,
1179                        'field_id'    => $field_id,
1180                        'option_id'    => $option_id)
1181                    );
1182                }
1183            }
1184        }
1185
1186        $db->sql_transaction('begin');
1187
1188        if ($action == 'create')
1189        {
1190            foreach ($profile_sql as $sql)
1191            {
1192                $db->sql_query($sql);
1193            }
1194        }
1195
1196        $db->sql_transaction('commit');
1197
1198        if ($action == 'edit')
1199        {
1200            $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PROFILE_FIELD_EDIT', false, array($cp->vars['field_ident'] . ':' . $cp->vars['lang_name']));
1201            trigger_error($user->lang['CHANGED_PROFILE_FIELD'] . adm_back_link($this->u_action));
1202        }
1203        else
1204        {
1205            $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PROFILE_FIELD_CREATE', false, array(substr($field_ident, 3) . ':' . $cp->vars['lang_name']));
1206            trigger_error($user->lang['ADDED_PROFILE_FIELD'] . adm_back_link($this->u_action));
1207        }
1208    }
1209
1210    /**
1211    * Update, then insert if not successfull
1212    */
1213    function update_insert($table, $sql_ary, $where_fields)
1214    {
1215        global $db;
1216
1217        $where_sql = array();
1218        $check_key = '';
1219
1220        foreach ($where_fields as $key => $value)
1221        {
1222            $check_key = (!$check_key) ? $key : $check_key;
1223            $where_sql[] = $key . ' = ' . ((is_string($value)) ? "'" . $db->sql_escape($value) . "'" : (int) $value);
1224        }
1225
1226        if (!count($where_sql))
1227        {
1228            return;
1229        }
1230
1231        $sql = "SELECT $check_key
1232            FROM $table
1233            WHERE " . implode(' AND ', $where_sql);
1234        $result = $db->sql_query($sql);
1235        $row = $db->sql_fetchrow($result);
1236        $db->sql_freeresult($result);
1237
1238        if (!$row)
1239        {
1240            $sql_ary = array_merge($where_fields, $sql_ary);
1241
1242            if (count($sql_ary))
1243            {
1244                $db->sql_query("INSERT INTO $table " . $db->sql_build_array('INSERT', $sql_ary));
1245            }
1246        }
1247        else
1248        {
1249            if (count($sql_ary))
1250            {
1251                $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql_ary) . '
1252                    WHERE ' . implode(' AND ', $where_sql);
1253                $db->sql_query($sql);
1254            }
1255        }
1256    }
1257}