[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id$ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * @ignore 13 */ 14 if (!defined('IN_PHPBB')) 15 { 16 exit; 17 } 18 19 /** 20 * Custom Profile Fields 21 * @package phpBB3 22 */ 23 class custom_profile 24 { 25 var $profile_types = array(FIELD_INT => 'int', FIELD_STRING => 'string', FIELD_TEXT => 'text', FIELD_BOOL => 'bool', FIELD_DROPDOWN => 'dropdown', FIELD_DATE => 'date'); 26 var $profile_cache = array(); 27 var $options_lang = array(); 28 29 /** 30 * Assign editable fields to template, mode can be profile (for profile change) or register (for registration) 31 * Called by ucp_profile and ucp_register 32 * @access public 33 */ 34 function generate_profile_fields($mode, $lang_id) 35 { 36 global $db, $template, $auth; 37 38 $sql_where = ''; 39 switch ($mode) 40 { 41 case 'register': 42 // If the field is required we show it on the registration page 43 $sql_where .= ' AND f.field_show_on_reg = 1'; 44 break; 45 46 case 'profile': 47 // Show hidden fields to moderators/admins 48 if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) 49 { 50 $sql_where .= ' AND f.field_show_profile = 1'; 51 } 52 break; 53 54 default: 55 trigger_error('Wrong profile mode specified', E_USER_ERROR); 56 break; 57 } 58 59 $sql = 'SELECT l.*, f.* 60 FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f 61 WHERE f.field_active = 1 62 $sql_where 63 AND l.lang_id = $lang_id 64 AND l.field_id = f.field_id 65 ORDER BY f.field_order"; 66 $result = $db->sql_query($sql); 67 68 while ($row = $db->sql_fetchrow($result)) 69 { 70 // Return templated field 71 $tpl_snippet = $this->process_field_row('change', $row); 72 73 // Some types are multivalue, we can't give them a field_id as we would not know which to pick 74 $type = (int) $row['field_type']; 75 76 $template->assign_block_vars('profile_fields', array( 77 'LANG_NAME' => $row['lang_name'], 78 'LANG_EXPLAIN' => $row['lang_explain'], 79 'FIELD' => $tpl_snippet, 80 'FIELD_ID' => ($type == FIELD_DATE || ($type == FIELD_BOOL && $row['field_length'] == '1')) ? '' : 'pf_' . $row['field_ident'], 81 'S_REQUIRED' => ($row['field_required']) ? true : false) 82 ); 83 } 84 $db->sql_freeresult($result); 85 } 86 87 /** 88 * Validate entered profile field data 89 * @access public 90 */ 91 function validate_profile_field($field_type, &$field_value, $field_data) 92 { 93 switch ($field_type) 94 { 95 case FIELD_DATE: 96 $field_validate = explode('-', $field_value); 97 98 $day = (isset($field_validate[0])) ? (int) $field_validate[0] : 0; 99 $month = (isset($field_validate[1])) ? (int) $field_validate[1] : 0; 100 $year = (isset($field_validate[2])) ? (int) $field_validate[2] : 0; 101 102 if ((!$day || !$month || !$year) && !$field_data['field_required']) 103 { 104 return false; 105 } 106 107 if ((!$day || !$month || !$year) && $field_data['field_required']) 108 { 109 return 'FIELD_REQUIRED'; 110 } 111 112 if ($day < 0 || $day > 31 || $month < 0 || $month > 12 || ($year < 1901 && $year > 0) || $year > gmdate('Y', time()) + 50) 113 { 114 return 'FIELD_INVALID_DATE'; 115 } 116 117 if (checkdate($month, $day, $year) === false) 118 { 119 return 'FIELD_INVALID_DATE'; 120 } 121 break; 122 123 case FIELD_BOOL: 124 $field_value = (bool) $field_value; 125 126 if (!$field_value && $field_data['field_required']) 127 { 128 return 'FIELD_REQUIRED'; 129 } 130 break; 131 132 case FIELD_INT: 133 if (trim($field_value) === '' && !$field_data['field_required']) 134 { 135 return false; 136 } 137 138 $field_value = (int) $field_value; 139 140 if ($field_value < $field_data['field_minlen']) 141 { 142 return 'FIELD_TOO_SMALL'; 143 } 144 else if ($field_value > $field_data['field_maxlen']) 145 { 146 return 'FIELD_TOO_LARGE'; 147 } 148 break; 149 150 case FIELD_DROPDOWN: 151 $field_value = (int) $field_value; 152 153 // retrieve option lang data if necessary 154 if (!isset($this->options_lang[$field_data['field_id']]) || !isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']]) || !sizeof($this->options_lang[$file_data['field_id']][$field_data['lang_id']])) 155 { 156 $this->get_option_lang($field_data['field_id'], $field_data['lang_id'], FIELD_DROPDOWN, false); 157 } 158 159 if (!isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']][$field_value])) 160 { 161 return 'FIELD_INVALID_VALUE'; 162 } 163 164 if ($field_value == $field_data['field_novalue'] && $field_data['field_required']) 165 { 166 return 'FIELD_REQUIRED'; 167 } 168 break; 169 170 case FIELD_STRING: 171 case FIELD_TEXT: 172 if (trim($field_value) === '' && !$field_data['field_required']) 173 { 174 return false; 175 } 176 else if (trim($field_value) === '' && $field_data['field_required']) 177 { 178 return 'FIELD_REQUIRED'; 179 } 180 181 if ($field_data['field_minlen'] && utf8_strlen($field_value) < $field_data['field_minlen']) 182 { 183 return 'FIELD_TOO_SHORT'; 184 } 185 else if ($field_data['field_maxlen'] && utf8_strlen($field_value) > $field_data['field_maxlen']) 186 { 187 return 'FIELD_TOO_LONG'; 188 } 189 190 if (!empty($field_data['field_validation']) && $field_data['field_validation'] != '.*') 191 { 192 $field_validate = ($field_type == FIELD_STRING) ? $field_value : bbcode_nl2br($field_value); 193 if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#i', $field_validate)) 194 { 195 return 'FIELD_INVALID_CHARS'; 196 } 197 } 198 break; 199 } 200 201 return false; 202 } 203 204 /** 205 * Build profile cache, used for display 206 * @access private 207 */ 208 function build_cache() 209 { 210 global $db, $user, $auth; 211 212 $this->profile_cache = array(); 213 214 // Display hidden/no_view fields for admin/moderator 215 $sql = 'SELECT l.*, f.* 216 FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f 217 WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' 218 AND f.field_active = 1 ' . 219 ((!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) ? ' AND f.field_hide = 0 ' : '') . ' 220 AND f.field_no_view = 0 221 AND l.field_id = f.field_id 222 ORDER BY f.field_order'; 223 $result = $db->sql_query($sql); 224 225 while ($row = $db->sql_fetchrow($result)) 226 { 227 $this->profile_cache[$row['field_ident']] = $row; 228 } 229 $db->sql_freeresult($result); 230 } 231 232 /** 233 * Get language entries for options and store them here for later use 234 */ 235 function get_option_lang($field_id, $lang_id, $field_type, $preview) 236 { 237 global $db; 238 239 if ($preview) 240 { 241 $lang_options = (!is_array($this->vars['lang_options'])) ? explode("\n", $this->vars['lang_options']) : $this->vars['lang_options']; 242 243 foreach ($lang_options as $num => $var) 244 { 245 $this->options_lang[$field_id][$lang_id][($num + 1)] = $var; 246 } 247 } 248 else 249 { 250 $sql = 'SELECT option_id, lang_value 251 FROM ' . PROFILE_FIELDS_LANG_TABLE . " 252 WHERE field_id = $field_id 253 AND lang_id = $lang_id 254 AND field_type = $field_type 255 ORDER BY option_id"; 256 $result = $db->sql_query($sql); 257 258 while ($row = $db->sql_fetchrow($result)) 259 { 260 $this->options_lang[$field_id][$lang_id][($row['option_id'] + 1)] = $row['lang_value']; 261 } 262 $db->sql_freeresult($result); 263 } 264 } 265 266 /** 267 * Submit profile field for validation 268 * @access public 269 */ 270 function submit_cp_field($mode, $lang_id, &$cp_data, &$cp_error) 271 { 272 global $auth, $db, $user; 273 274 $sql_where = ''; 275 switch ($mode) 276 { 277 case 'register': 278 // If the field is required we show it on the registration page 279 $sql_where .= ' AND f.field_show_on_reg = 1'; 280 break; 281 282 case 'profile': 283 // Show hidden fields to moderators/admins 284 if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) 285 { 286 $sql_where .= ' AND f.field_show_profile = 1'; 287 } 288 break; 289 290 default: 291 trigger_error('Wrong profile mode specified', E_USER_ERROR); 292 break; 293 } 294 295 $sql = 'SELECT l.*, f.* 296 FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f 297 WHERE l.lang_id = $lang_id 298 AND f.field_active = 1 299 $sql_where 300 AND l.field_id = f.field_id 301 ORDER BY f.field_order"; 302 $result = $db->sql_query($sql); 303 304 while ($row = $db->sql_fetchrow($result)) 305 { 306 $cp_data['pf_' . $row['field_ident']] = $this->get_profile_field($row); 307 $check_value = $cp_data['pf_' . $row['field_ident']]; 308 309 if (($cp_result = $this->validate_profile_field($row['field_type'], $check_value, $row)) !== false) 310 { 311 // If not and only showing common error messages, use this one 312 $error = ''; 313 switch ($cp_result) 314 { 315 case 'FIELD_INVALID_DATE': 316 case 'FIELD_INVALID_VALUE': 317 case 'FIELD_REQUIRED': 318 $error = sprintf($user->lang[$cp_result], $row['lang_name']); 319 break; 320 321 case 'FIELD_TOO_SHORT': 322 case 'FIELD_TOO_SMALL': 323 $error = sprintf($user->lang[$cp_result], $row['lang_name'], $row['field_minlen']); 324 break; 325 326 case 'FIELD_TOO_LONG': 327 case 'FIELD_TOO_LARGE': 328 $error = sprintf($user->lang[$cp_result], $row['lang_name'], $row['field_maxlen']); 329 break; 330 331 case 'FIELD_INVALID_CHARS': 332 switch ($row['field_validation']) 333 { 334 case '[0-9]+': 335 $error = sprintf($user->lang[$cp_result . '_NUMBERS_ONLY'], $row['lang_name']); 336 break; 337 338 case '[\w]+': 339 $error = sprintf($user->lang[$cp_result . '_ALPHA_ONLY'], $row['lang_name']); 340 break; 341 342 case '[\w_\+\. \-\[\]]+': 343 $error = sprintf($user->lang[$cp_result . '_SPACERS_ONLY'], $row['lang_name']); 344 break; 345 } 346 break; 347 } 348 349 if ($error != '') 350 { 351 $cp_error[] = $error; 352 } 353 } 354 } 355 $db->sql_freeresult($result); 356 } 357 358 /** 359 * Update profile field data directly 360 */ 361 function update_profile_field_data($user_id, &$cp_data) 362 { 363 global $db; 364 365 if (!sizeof($cp_data)) 366 { 367 return; 368 } 369 370 switch ($db->sql_layer) 371 { 372 case 'oracle': 373 case 'firebird': 374 case 'postgres': 375 $right_delim = $left_delim = '"'; 376 break; 377 378 case 'sqlite': 379 case 'mssql': 380 case 'mssql_odbc': 381 case 'mssqlnative': 382 $right_delim = ']'; 383 $left_delim = '['; 384 break; 385 386 case 'mysql': 387 case 'mysql4': 388 case 'mysqli': 389 $right_delim = $left_delim = '`'; 390 break; 391 } 392 393 // use new array for the UPDATE; changes in the key do not affect the original array 394 $cp_data_sql = array(); 395 foreach ($cp_data as $key => $value) 396 { 397 // Firebird is case sensitive with delimiter 398 $cp_data_sql[$left_delim . (($db->sql_layer == 'firebird' || $db->sql_layer == 'oracle') ? strtoupper($key) : $key) . $right_delim] = $value; 399 } 400 401 $sql = 'UPDATE ' . PROFILE_FIELDS_DATA_TABLE . ' 402 SET ' . $db->sql_build_array('UPDATE', $cp_data_sql) . " 403 WHERE user_id = $user_id"; 404 $db->sql_query($sql); 405 406 if (!$db->sql_affectedrows()) 407 { 408 $cp_data_sql['user_id'] = (int) $user_id; 409 410 $db->sql_return_on_error(true); 411 412 $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $cp_data_sql); 413 $db->sql_query($sql); 414 415 $db->sql_return_on_error(false); 416 } 417 } 418 419 /** 420 * Assign fields to template, used for viewprofile, viewtopic and memberlist (if load setting is enabled) 421 * This is directly connected to the user -> mode == grab is to grab the user specific fields, mode == show is for assigning the row to the template 422 * @access public 423 */ 424 function generate_profile_fields_template($mode, $user_id = 0, $profile_row = false) 425 { 426 global $db; 427 428 if ($mode == 'grab') 429 { 430 if (!is_array($user_id)) 431 { 432 $user_id = array($user_id); 433 } 434 435 if (!sizeof($this->profile_cache)) 436 { 437 $this->build_cache(); 438 } 439 440 if (!sizeof($user_id)) 441 { 442 return array(); 443 } 444 445 $sql = 'SELECT * 446 FROM ' . PROFILE_FIELDS_DATA_TABLE . ' 447 WHERE ' . $db->sql_in_set('user_id', array_map('intval', $user_id)); 448 $result = $db->sql_query($sql); 449 450 $field_data = array(); 451 while ($row = $db->sql_fetchrow($result)) 452 { 453 $field_data[$row['user_id']] = $row; 454 } 455 $db->sql_freeresult($result); 456 457 $user_fields = array(); 458 459 $user_ids = $user_id; 460 461 // Go through the fields in correct order 462 foreach (array_keys($this->profile_cache) as $used_ident) 463 { 464 foreach ($field_data as $user_id => $row) 465 { 466 $user_fields[$user_id][$used_ident]['value'] = $row['pf_' . $used_ident]; 467 $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; 468 } 469 470 foreach ($user_ids as $user_id) 471 { 472 if (!isset($user_fields[$user_id][$used_ident]) && $this->profile_cache[$used_ident]['field_show_novalue']) 473 { 474 $user_fields[$user_id][$used_ident]['value'] = ''; 475 $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; 476 } 477 } 478 } 479 480 return $user_fields; 481 } 482 else if ($mode == 'show') 483 { 484 // $profile_row == $user_fields[$row['user_id']]; 485 $tpl_fields = array(); 486 $tpl_fields['row'] = $tpl_fields['blockrow'] = array(); 487 488 foreach ($profile_row as $ident => $ident_ary) 489 { 490 $value = $this->get_profile_value($ident_ary); 491 492 if ($value === NULL) 493 { 494 continue; 495 } 496 497 $tpl_fields['row'] += array( 498 'PROFILE_' . strtoupper($ident) . '_VALUE' => $value, 499 'PROFILE_' . strtoupper($ident) . '_TYPE' => $ident_ary['data']['field_type'], 500 'PROFILE_' . strtoupper($ident) . '_NAME' => $ident_ary['data']['lang_name'], 501 'PROFILE_' . strtoupper($ident) . '_EXPLAIN'=> $ident_ary['data']['lang_explain'], 502 503 'S_PROFILE_' . strtoupper($ident) => true 504 ); 505 506 $tpl_fields['blockrow'][] = array( 507 'PROFILE_FIELD_VALUE' => $value, 508 'PROFILE_FIELD_TYPE' => $ident_ary['data']['field_type'], 509 'PROFILE_FIELD_NAME' => $ident_ary['data']['lang_name'], 510 'PROFILE_FIELD_EXPLAIN' => $ident_ary['data']['lang_explain'], 511 512 'S_PROFILE_' . strtoupper($ident) => true 513 ); 514 } 515 516 return $tpl_fields; 517 } 518 else 519 { 520 trigger_error('Wrong mode for custom profile', E_USER_ERROR); 521 } 522 } 523 524 /** 525 * Get Profile Value for display 526 */ 527 function get_profile_value($ident_ary) 528 { 529 $value = $ident_ary['value']; 530 $field_type = $ident_ary['data']['field_type']; 531 532 switch ($this->profile_types[$field_type]) 533 { 534 case 'int': 535 if ($value === '' && !$ident_ary['data']['field_show_novalue']) 536 { 537 return NULL; 538 } 539 return (int) $value; 540 break; 541 542 case 'string': 543 case 'text': 544 if (!$value && !$ident_ary['data']['field_show_novalue']) 545 { 546 return NULL; 547 } 548 549 $value = make_clickable($value); 550 $value = censor_text($value); 551 $value = bbcode_nl2br($value); 552 return $value; 553 break; 554 555 // case 'datetime': 556 case 'date': 557 $date = explode('-', $value); 558 $day = (isset($date[0])) ? (int) $date[0] : 0; 559 $month = (isset($date[1])) ? (int) $date[1] : 0; 560 $year = (isset($date[2])) ? (int) $date[2] : 0; 561 562 if (!$day && !$month && !$year && !$ident_ary['data']['field_show_novalue']) 563 { 564 return NULL; 565 } 566 else if ($day && $month && $year) 567 { 568 global $user; 569 // Date should display as the same date for every user regardless of timezone, so remove offset 570 // to compensate for the offset added by user::format_date() 571 return $user->format_date(gmmktime(0, 0, 0, $month, $day, $year) - ($user->timezone + $user->dst), $user->lang['DATE_FORMAT'], true); 572 } 573 574 return $value; 575 break; 576 577 case 'dropdown': 578 $field_id = $ident_ary['data']['field_id']; 579 $lang_id = $ident_ary['data']['lang_id']; 580 if (!isset($this->options_lang[$field_id][$lang_id])) 581 { 582 $this->get_option_lang($field_id, $lang_id, FIELD_DROPDOWN, false); 583 } 584 585 if ($value == $ident_ary['data']['field_novalue'] && !$ident_ary['data']['field_show_novalue']) 586 { 587 return NULL; 588 } 589 590 $value = (int) $value; 591 592 // User not having a value assigned 593 if (!isset($this->options_lang[$field_id][$lang_id][$value])) 594 { 595 if ($ident_ary['data']['field_show_novalue']) 596 { 597 $value = $ident_ary['data']['field_novalue']; 598 } 599 else 600 { 601 return NULL; 602 } 603 } 604 605 return $this->options_lang[$field_id][$lang_id][$value]; 606 break; 607 608 case 'bool': 609 $field_id = $ident_ary['data']['field_id']; 610 $lang_id = $ident_ary['data']['lang_id']; 611 if (!isset($this->options_lang[$field_id][$lang_id])) 612 { 613 $this->get_option_lang($field_id, $lang_id, FIELD_BOOL, false); 614 } 615 616 if (!$value && $ident_ary['data']['field_show_novalue']) 617 { 618 $value = $ident_ary['data']['field_default_value']; 619 } 620 621 if ($ident_ary['data']['field_length'] == 1) 622 { 623 return (isset($this->options_lang[$field_id][$lang_id][(int) $value])) ? $this->options_lang[$field_id][$lang_id][(int) $value] : NULL; 624 } 625 else if (!$value) 626 { 627 return NULL; 628 } 629 else 630 { 631 return $this->options_lang[$field_id][$lang_id][(int) ($value) + 1]; 632 } 633 break; 634 635 default: 636 trigger_error('Unknown profile type', E_USER_ERROR); 637 break; 638 } 639 } 640 641 /** 642 * Get field value for registration/profile 643 * @access private 644 */ 645 function get_var($field_validation, &$profile_row, $default_value, $preview) 646 { 647 global $user; 648 649 $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; 650 $user_ident = $profile_row['field_ident']; 651 // checkbox - set the value to "true" if it has been set to 1 652 if ($profile_row['field_type'] == FIELD_BOOL && $profile_row['field_length'] == 2) 653 { 654 $value = (isset($_REQUEST[$profile_row['field_ident']]) && request_var($profile_row['field_ident'], $default_value) == 1) ? true : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); 655 } 656 else if ($profile_row['field_type'] == FIELD_INT) 657 { 658 if (isset($_REQUEST[$profile_row['field_ident']])) 659 { 660 $value = ($_REQUEST[$profile_row['field_ident']] === '') ? NULL : request_var($profile_row['field_ident'], $default_value); 661 } 662 else 663 { 664 if (!$preview && array_key_exists($user_ident, $user->profile_fields) && is_null($user->profile_fields[$user_ident])) 665 { 666 $value = NULL; 667 } 668 else if (!isset($user->profile_fields[$user_ident]) || $preview) 669 { 670 $value = $default_value; 671 } 672 else 673 { 674 $value = $user->profile_fields[$user_ident]; 675 } 676 } 677 678 return (is_null($value) || $value === '') ? '' : (int) $value; 679 } 680 else 681 { 682 $value = (isset($_REQUEST[$profile_row['field_ident']])) ? request_var($profile_row['field_ident'], $default_value, true) : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); 683 684 if (gettype($value) == 'string') 685 { 686 $value = utf8_normalize_nfc($value); 687 } 688 } 689 690 switch ($field_validation) 691 { 692 case 'int': 693 return (int) $value; 694 break; 695 } 696 697 return $value; 698 } 699 700 /** 701 * Process int-type 702 * @access private 703 */ 704 function generate_int($profile_row, $preview = false) 705 { 706 global $template; 707 708 $profile_row['field_value'] = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); 709 $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); 710 } 711 712 /** 713 * Process date-type 714 * @access private 715 */ 716 function generate_date($profile_row, $preview = false) 717 { 718 global $user, $template; 719 720 $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; 721 $user_ident = $profile_row['field_ident']; 722 723 $now = getdate(); 724 725 if (!isset($_REQUEST[$profile_row['field_ident'] . '_day'])) 726 { 727 if ($profile_row['field_default_value'] == 'now') 728 { 729 $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); 730 } 731 list($day, $month, $year) = explode('-', ((!isset($user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $user->profile_fields[$user_ident])); 732 } 733 else 734 { 735 if ($preview && $profile_row['field_default_value'] == 'now') 736 { 737 $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); 738 list($day, $month, $year) = explode('-', ((!isset($user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $user->profile_fields[$user_ident])); 739 } 740 else 741 { 742 $day = request_var($profile_row['field_ident'] . '_day', 0); 743 $month = request_var($profile_row['field_ident'] . '_month', 0); 744 $year = request_var($profile_row['field_ident'] . '_year', 0); 745 } 746 } 747 748 $profile_row['s_day_options'] = '<option value="0"' . ((!$day) ? ' selected="selected"' : '') . '>--</option>'; 749 for ($i = 1; $i < 32; $i++) 750 { 751 $profile_row['s_day_options'] .= '<option value="' . $i . '"' . (($i == $day) ? ' selected="selected"' : '') . ">$i</option>"; 752 } 753 754 $profile_row['s_month_options'] = '<option value="0"' . ((!$month) ? ' selected="selected"' : '') . '>--</option>'; 755 for ($i = 1; $i < 13; $i++) 756 { 757 $profile_row['s_month_options'] .= '<option value="' . $i . '"' . (($i == $month) ? ' selected="selected"' : '') . ">$i</option>"; 758 } 759 760 $profile_row['s_year_options'] = '<option value="0"' . ((!$year) ? ' selected="selected"' : '') . '>--</option>'; 761 for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) 762 { 763 $profile_row['s_year_options'] .= '<option value="' . $i . '"' . (($i == $year) ? ' selected="selected"' : '') . ">$i</option>"; 764 } 765 unset($now); 766 767 $profile_row['field_value'] = 0; 768 $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); 769 } 770 771 /** 772 * Process bool-type 773 * @access private 774 */ 775 function generate_bool($profile_row, $preview = false) 776 { 777 global $template; 778 779 $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); 780 781 $profile_row['field_value'] = $value; 782 $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); 783 784 if ($profile_row['field_length'] == 1) 785 { 786 if (!isset($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']]) || !sizeof($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']])) 787 { 788 $this->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], FIELD_BOOL, $preview); 789 } 790 791 foreach ($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']] as $option_id => $option_value) 792 { 793 $template->assign_block_vars('bool.options', array( 794 'OPTION_ID' => $option_id, 795 'CHECKED' => ($value == $option_id) ? ' checked="checked"' : '', 796 'VALUE' => $option_value) 797 ); 798 } 799 } 800 } 801 802 /** 803 * Process string-type 804 * @access private 805 */ 806 function generate_string($profile_row, $preview = false) 807 { 808 global $template; 809 810 $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); 811 $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); 812 } 813 814 /** 815 * Process text-type 816 * @access private 817 */ 818 function generate_text($profile_row, $preview = false) 819 { 820 global $template; 821 global $user, $phpEx, $phpbb_root_path; 822 823 $field_length = explode('|', $profile_row['field_length']); 824 $profile_row['field_rows'] = $field_length[0]; 825 $profile_row['field_cols'] = $field_length[1]; 826 827 $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); 828 $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); 829 } 830 831 /** 832 * Process dropdown-type 833 * @access private 834 */ 835 function generate_dropdown($profile_row, $preview = false) 836 { 837 global $user, $template; 838 839 $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); 840 841 if (!isset($this->options_lang[$profile_row['field_id']]) || !isset($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']]) || !sizeof($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']])) 842 { 843 $this->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], FIELD_DROPDOWN, $preview); 844 } 845 846 $profile_row['field_value'] = $value; 847 $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); 848 849 foreach ($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']] as $option_id => $option_value) 850 { 851 $template->assign_block_vars('dropdown.options', array( 852 'OPTION_ID' => $option_id, 853 'SELECTED' => ($value == $option_id) ? ' selected="selected"' : '', 854 'VALUE' => $option_value) 855 ); 856 } 857 } 858 859 /** 860 * Return Templated value/field. Possible values for $mode are: 861 * change == user is able to set/enter profile values; preview == just show the value 862 * @access private 863 */ 864 function process_field_row($mode, $profile_row) 865 { 866 global $template; 867 868 $preview = ($mode == 'preview') ? true : false; 869 870 // set template filename 871 $template->set_filenames(array( 872 'cp_body' => 'custom_profile_fields.html') 873 ); 874 875 // empty previously filled blockvars 876 foreach ($this->profile_types as $field_case => $field_type) 877 { 878 $template->destroy_block_vars($field_type); 879 } 880 881 // Assign template variables 882 $type_func = 'generate_' . $this->profile_types[$profile_row['field_type']]; 883 $this->$type_func($profile_row, $preview); 884 885 // Return templated data 886 return $template->assign_display('cp_body'); 887 } 888 889 /** 890 * Build Array for user insertion into custom profile fields table 891 */ 892 function build_insert_sql_array($cp_data) 893 { 894 global $db, $user, $auth; 895 896 $sql_not_in = array(); 897 foreach ($cp_data as $key => $null) 898 { 899 $sql_not_in[] = (strncmp($key, 'pf_', 3) === 0) ? substr($key, 3) : $key; 900 } 901 902 $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value 903 FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f 904 WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' 905 ' . ((sizeof($sql_not_in)) ? ' AND ' . $db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . ' 906 AND l.field_id = f.field_id'; 907 $result = $db->sql_query($sql); 908 909 while ($row = $db->sql_fetchrow($result)) 910 { 911 if ($row['field_default_value'] == 'now' && $row['field_type'] == FIELD_DATE) 912 { 913 $now = getdate(); 914 $row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); 915 } 916 else if ($row['field_default_value'] === '' && $row['field_type'] == FIELD_INT) 917 { 918 // We cannot insert an empty string into an integer column. 919 $row['field_default_value'] = NULL; 920 } 921 922 $cp_data['pf_' . $row['field_ident']] = (in_array($row['field_type'], array(FIELD_TEXT, FIELD_STRING))) ? $row['lang_default_value'] : $row['field_default_value']; 923 } 924 $db->sql_freeresult($result); 925 926 return $cp_data; 927 } 928 929 /** 930 * Get profile field value on submit 931 * @access private 932 */ 933 function get_profile_field($profile_row) 934 { 935 global $phpbb_root_path, $phpEx; 936 global $config; 937 938 $var_name = 'pf_' . $profile_row['field_ident']; 939 940 switch ($profile_row['field_type']) 941 { 942 case FIELD_DATE: 943 944 if (!isset($_REQUEST[$var_name . '_day'])) 945 { 946 if ($profile_row['field_default_value'] == 'now') 947 { 948 $now = getdate(); 949 $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); 950 } 951 list($day, $month, $year) = explode('-', $profile_row['field_default_value']); 952 } 953 else 954 { 955 $day = request_var($var_name . '_day', 0); 956 $month = request_var($var_name . '_month', 0); 957 $year = request_var($var_name . '_year', 0); 958 } 959 960 $var = sprintf('%2d-%2d-%4d', $day, $month, $year); 961 break; 962 963 case FIELD_BOOL: 964 // Checkbox 965 if ($profile_row['field_length'] == 2) 966 { 967 $var = (isset($_REQUEST[$var_name])) ? 1 : 0; 968 } 969 else 970 { 971 $var = request_var($var_name, (int) $profile_row['field_default_value']); 972 } 973 break; 974 975 case FIELD_STRING: 976 case FIELD_TEXT: 977 $var = utf8_normalize_nfc(request_var($var_name, (string) $profile_row['field_default_value'], true)); 978 break; 979 980 case FIELD_INT: 981 if (isset($_REQUEST[$var_name]) && $_REQUEST[$var_name] === '') 982 { 983 $var = NULL; 984 } 985 else 986 { 987 $var = request_var($var_name, (int) $profile_row['field_default_value']); 988 } 989 break; 990 991 case FIELD_DROPDOWN: 992 $var = request_var($var_name, (int) $profile_row['field_default_value']); 993 break; 994 995 default: 996 $var = request_var($var_name, $profile_row['field_default_value']); 997 break; 998 } 999 1000 return $var; 1001 } 1002 } 1003 1004 /** 1005 * Custom Profile Fields ACP 1006 * @package phpBB3 1007 */ 1008 class custom_profile_admin extends custom_profile 1009 { 1010 var $vars = array(); 1011 1012 /** 1013 * Return possible validation options 1014 */ 1015 function validate_options() 1016 { 1017 global $user; 1018 1019 $validate_ary = array('CHARS_ANY' => '.*', 'NUMBERS_ONLY' => '[0-9]+', 'ALPHA_ONLY' => '[\w]+', 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+'); 1020 1021 $validate_options = ''; 1022 foreach ($validate_ary as $lang => $value) 1023 { 1024 $selected = ($this->vars['field_validation'] == $value) ? ' selected="selected"' : ''; 1025 $validate_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$lang] . '</option>'; 1026 } 1027 1028 return $validate_options; 1029 } 1030 1031 /** 1032 * Get string options for second step in ACP 1033 */ 1034 function get_string_options() 1035 { 1036 global $user; 1037 1038 $options = array( 1039 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="text" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), 1040 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), 1041 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'), 1042 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') 1043 ); 1044 1045 return $options; 1046 } 1047 1048 /** 1049 * Get text options for second step in ACP 1050 */ 1051 function get_text_options() 1052 { 1053 global $user; 1054 1055 $options = array( 1056 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input name="rows" size="5" value="' . $this->vars['rows'] . '" /> ' . $user->lang['ROWS'] . '</dd><dd><input name="columns" size="5" value="' . $this->vars['columns'] . '" /> ' . $user->lang['COLUMNS'] . ' <input type="hidden" name="field_length" value="' . $this->vars['field_length'] . '" />'), 1057 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_minlen" size="10" value="' . $this->vars['field_minlen'] . '" />'), 1058 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_maxlen" size="10" value="' . $this->vars['field_maxlen'] . '" />'), 1059 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') 1060 ); 1061 1062 return $options; 1063 } 1064 1065 /** 1066 * Get int options for second step in ACP 1067 */ 1068 function get_int_options() 1069 { 1070 global $user; 1071 1072 $options = array( 1073 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="text" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), 1074 1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="text" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), 1075 2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="text" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'), 1076 3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '<input type="post" name="field_default_value" value="' . $this->vars['field_default_value'] . '" />') 1077 ); 1078 1079 return $options; 1080 } 1081 1082 /** 1083 * Get bool options for second step in ACP 1084 */ 1085 function get_bool_options() 1086 { 1087 global $user, $config, $lang_defs; 1088 1089 $default_lang_id = $lang_defs['iso'][$config['default_lang']]; 1090 1091 $profile_row = array( 1092 'var_name' => 'field_default_value', 1093 'field_id' => 1, 1094 'lang_name' => $this->vars['lang_name'], 1095 'lang_explain' => $this->vars['lang_explain'], 1096 'lang_id' => $default_lang_id, 1097 'field_default_value' => $this->vars['field_default_value'], 1098 'field_ident' => 'field_default_value', 1099 'field_type' => FIELD_BOOL, 1100 'field_length' => $this->vars['field_length'], 1101 'lang_options' => $this->vars['lang_options'] 1102 ); 1103 1104 $options = array( 1105 0 => array('TITLE' => $user->lang['FIELD_TYPE'], 'EXPLAIN' => $user->lang['BOOL_TYPE_EXPLAIN'], 'FIELD' => '<label><input type="radio" class="radio" name="field_length" value="1"' . (($this->vars['field_length'] == 1) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['RADIO_BUTTONS'] . '</label><label><input type="radio" class="radio" name="field_length" value="2"' . (($this->vars['field_length'] == 2) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['CHECKBOX'] . '</label>'), 1106 1 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)) 1107 ); 1108 1109 return $options; 1110 } 1111 1112 /** 1113 * Get dropdown options for second step in ACP 1114 */ 1115 function get_dropdown_options() 1116 { 1117 global $user, $config, $lang_defs; 1118 1119 $default_lang_id = $lang_defs['iso'][$config['default_lang']]; 1120 1121 $profile_row[0] = array( 1122 'var_name' => 'field_default_value', 1123 'field_id' => 1, 1124 'lang_name' => $this->vars['lang_name'], 1125 'lang_explain' => $this->vars['lang_explain'], 1126 'lang_id' => $default_lang_id, 1127 'field_default_value' => $this->vars['field_default_value'], 1128 'field_ident' => 'field_default_value', 1129 'field_type' => FIELD_DROPDOWN, 1130 'lang_options' => $this->vars['lang_options'] 1131 ); 1132 1133 $profile_row[1] = $profile_row[0]; 1134 $profile_row[1]['var_name'] = 'field_novalue'; 1135 $profile_row[1]['field_ident'] = 'field_novalue'; 1136 $profile_row[1]['field_default_value'] = $this->vars['field_novalue']; 1137 1138 $options = array( 1139 0 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row[0])), 1140 1 => array('TITLE' => $user->lang['NO_VALUE_OPTION'], 'EXPLAIN' => $user->lang['NO_VALUE_OPTION_EXPLAIN'], 'FIELD' => $this->process_field_row('preview', $profile_row[1])) 1141 ); 1142 1143 return $options; 1144 } 1145 1146 /** 1147 * Get date options for second step in ACP 1148 */ 1149 function get_date_options() 1150 { 1151 global $user, $config, $lang_defs; 1152 1153 $default_lang_id = $lang_defs['iso'][$config['default_lang']]; 1154 1155 $profile_row = array( 1156 'var_name' => 'field_default_value', 1157 'lang_name' => $this->vars['lang_name'], 1158 'lang_explain' => $this->vars['lang_explain'], 1159 'lang_id' => $default_lang_id, 1160 'field_default_value' => $this->vars['field_default_value'], 1161 'field_ident' => 'field_default_value', 1162 'field_type' => FIELD_DATE, 1163 'field_length' => $this->vars['field_length'] 1164 ); 1165 1166 $always_now = request_var('always_now', -1); 1167 if ($always_now == -1) 1168 { 1169 $s_checked = ($this->vars['field_default_value'] == 'now') ? true : false; 1170 } 1171 else 1172 { 1173 $s_checked = ($always_now) ? true : false; 1174 } 1175 1176 $options = array( 1177 0 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)), 1178 1 => array('TITLE' => $user->lang['ALWAYS_TODAY'], 'FIELD' => '<label><input type="radio" class="radio" name="always_now" value="1"' . (($s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['YES'] . '</label><label><input type="radio" class="radio" name="always_now" value="0"' . ((!$s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['NO'] . '</label>'), 1179 ); 1180 1181 return $options; 1182 } 1183 } 1184 1185 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Oct 2 15:03:47 2013 | Cross-referenced by PHPXref 0.7.1 |