[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/phpbb/profilefields/ -> manager.php (source)

   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  namespace phpbb\profilefields;
  15  
  16  /**
  17  * Custom Profile Fields
  18  */
  19  class manager
  20  {
  21      /**
  22      * Auth object
  23      * @var \phpbb\auth\auth
  24      */
  25      protected $auth;
  26  
  27      /**
  28      * Database object
  29      * @var \phpbb\db\driver\driver_interface
  30      */
  31      protected $db;
  32  
  33      /**
  34      * Event dispatcher object
  35      * @var \phpbb\event\dispatcher_interface
  36      */
  37      protected $dispatcher;
  38  
  39      /**
  40      * Request object
  41      * @var \phpbb\request\request
  42      */
  43      protected $request;
  44  
  45      /**
  46      * Template object
  47      * @var \phpbb\template\template
  48      */
  49      protected $template;
  50  
  51      /**
  52      * Service Collection object
  53      * @var \phpbb\di\service_collection
  54      */
  55      protected $type_collection;
  56  
  57      /**
  58      * User object
  59      * @var \phpbb\user
  60      */
  61      protected $user;
  62  
  63      protected $fields_table;
  64  
  65      protected $fields_language_table;
  66  
  67      protected $fields_data_table;
  68  
  69      protected $profile_cache = array();
  70  
  71      /**
  72      * Construct
  73      *
  74      * @param    \phpbb\auth\auth            $auth        Auth object
  75      * @param    \phpbb\db\driver\driver_interface    $db            Database object
  76      * @param    \phpbb\event\dispatcher_interface        $dispatcher    Event dispatcher object
  77      * @param    \phpbb\request\request        $request    Request object
  78      * @param    \phpbb\template\template    $template    Template object
  79      * @param    \phpbb\di\service_collection $type_collection
  80      * @param    \phpbb\user                    $user        User object
  81      * @param    string                $fields_table
  82      * @param    string                $fields_language_table
  83      * @param    string                $fields_data_table
  84      */
  85  	public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
  86      {
  87          $this->auth = $auth;
  88          $this->db = $db;
  89          $this->dispatcher = $dispatcher;
  90          $this->request = $request;
  91          $this->template = $template;
  92          $this->type_collection = $type_collection;
  93          $this->user = $user;
  94  
  95          $this->fields_table = $fields_table;
  96          $this->fields_language_table = $fields_language_table;
  97          $this->fields_data_table = $fields_data_table;
  98      }
  99  
 100      /**
 101      * Assign editable fields to template, mode can be profile (for profile change) or register (for registration)
 102      * Called by ucp_profile and ucp_register
 103      */
 104  	public function generate_profile_fields($mode, $lang_id)
 105      {
 106          $sql_where = '';
 107          switch ($mode)
 108          {
 109              case 'register':
 110                  // If the field is required we show it on the registration page
 111                  $sql_where .= ' AND f.field_show_on_reg = 1';
 112              break;
 113  
 114              case 'profile':
 115                  // Show hidden fields to moderators/admins
 116                  if (!$this->auth->acl_gets('a_', 'm_') && !$this->auth->acl_getf_global('m_'))
 117                  {
 118                      $sql_where .= ' AND f.field_show_profile = 1';
 119                  }
 120              break;
 121  
 122              default:
 123                  trigger_error('Wrong profile mode specified', E_USER_ERROR);
 124              break;
 125          }
 126  
 127          $sql = 'SELECT l.*, f.*
 128              FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . " f
 129              WHERE f.field_active = 1
 130                  $sql_where
 131                  AND l.lang_id = " . (int) $lang_id . '
 132                  AND l.field_id = f.field_id
 133              ORDER BY f.field_order';
 134          $result = $this->db->sql_query($sql);
 135  
 136          while ($row = $this->db->sql_fetchrow($result))
 137          {
 138              // Return templated field
 139              $profile_field = $this->type_collection[$row['field_type']];
 140              $tpl_snippet = $profile_field->process_field_row('change', $row);
 141  
 142              $this->template->assign_block_vars('profile_fields', array(
 143                  'LANG_NAME'        => $this->user->lang($row['lang_name']),
 144                  'LANG_EXPLAIN'    => $this->user->lang($row['lang_explain']),
 145                  'FIELD'            => $tpl_snippet,
 146                  'FIELD_ID'        => $profile_field->get_field_ident($row),
 147                  'S_REQUIRED'    => ($row['field_required']) ? true : false,
 148              ));
 149          }
 150          $this->db->sql_freeresult($result);
 151      }
 152  
 153      /**
 154      * Build profile cache, used for display
 155      */
 156  	protected function build_cache()
 157      {
 158          $this->profile_cache = array();
 159  
 160          // Display hidden/no_view fields for admin/moderator
 161          $sql = 'SELECT l.*, f.*
 162              FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f
 163              WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . '
 164                  AND f.field_active = 1 ' .
 165                  ((!$this->auth->acl_gets('a_', 'm_') && !$this->auth->acl_getf_global('m_')) ? '    AND f.field_hide = 0 ' : '') . '
 166                  AND f.field_no_view = 0
 167                  AND l.field_id = f.field_id
 168              ORDER BY f.field_order';
 169          $result = $this->db->sql_query($sql);
 170  
 171          while ($row = $this->db->sql_fetchrow($result))
 172          {
 173              $this->profile_cache[$row['field_ident']] = $row;
 174          }
 175          $this->db->sql_freeresult($result);
 176      }
 177  
 178      /**
 179      * Submit profile field for validation
 180      */
 181  	public function submit_cp_field($mode, $lang_id, &$cp_data, &$cp_error)
 182      {
 183          $sql_where = '';
 184          switch ($mode)
 185          {
 186              case 'register':
 187                  // If the field is required we show it on the registration page
 188                  $sql_where .= ' AND f.field_show_on_reg = 1';
 189              break;
 190  
 191              case 'profile':
 192                  // Show hidden fields to moderators/admins
 193                  if (!$this->auth->acl_gets('a_', 'm_') && !$this->auth->acl_getf_global('m_'))
 194                  {
 195                      $sql_where .= ' AND f.field_show_profile = 1';
 196                  }
 197              break;
 198  
 199              default:
 200                  trigger_error('Wrong profile mode specified', E_USER_ERROR);
 201              break;
 202          }
 203  
 204          $sql = 'SELECT l.*, f.*
 205              FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f
 206              WHERE l.lang_id = ' . (int) $lang_id . "
 207                  AND f.field_active = 1
 208                  $sql_where
 209                  AND l.field_id = f.field_id
 210              ORDER BY f.field_order";
 211          $result = $this->db->sql_query($sql);
 212  
 213          while ($row = $this->db->sql_fetchrow($result))
 214          {
 215              $profile_field = $this->type_collection[$row['field_type']];
 216              $cp_data['pf_' . $row['field_ident']] = $profile_field->get_profile_field($row);
 217              $check_value = $cp_data['pf_' . $row['field_ident']];
 218  
 219              if (($cp_result = $profile_field->validate_profile_field($check_value, $row)) !== false)
 220              {
 221                  // If the result is not false, it's an error message
 222                  $cp_error[] = $cp_result;
 223              }
 224          }
 225          $this->db->sql_freeresult($result);
 226      }
 227  
 228      /**
 229      * Update profile field data directly
 230      */
 231  	public function update_profile_field_data($user_id, $cp_data)
 232      {
 233          if (!sizeof($cp_data))
 234          {
 235              return;
 236          }
 237  
 238          $sql = 'UPDATE ' . $this->fields_data_table . '
 239              SET ' . $this->db->sql_build_array('UPDATE', $cp_data) . '
 240              WHERE user_id = ' . (int) $user_id;
 241          $this->db->sql_query($sql);
 242  
 243          if (!$this->db->sql_affectedrows())
 244          {
 245              $cp_data = $this->build_insert_sql_array($cp_data);
 246              $cp_data['user_id'] = (int) $user_id;
 247  
 248              $sql = 'INSERT INTO ' . $this->fields_data_table . ' ' . $this->db->sql_build_array('INSERT', $cp_data);
 249              $this->db->sql_query($sql);
 250          }
 251      }
 252  
 253      /**
 254      * Generate the template arrays in order to display the column names
 255      *
 256      * @param string    $restrict_option    Restrict the published fields to a certain profile field option
 257      * @return array        Returns an array with the template variables type, name and explain for the fields to display
 258      */
 259  	public function generate_profile_fields_template_headlines($restrict_option = '')
 260      {
 261          if (!sizeof($this->profile_cache))
 262          {
 263              $this->build_cache();
 264          }
 265  
 266          $tpl_fields = array();
 267  
 268          // Go through the fields in correct order
 269          foreach ($this->profile_cache as $field_ident => $field_data)
 270          {
 271              if ($restrict_option && !$field_data[$restrict_option])
 272              {
 273                  continue;
 274              }
 275  
 276              $profile_field = $this->type_collection[$field_data['field_type']];
 277  
 278              $tpl_fields[] = array(
 279                  'PROFILE_FIELD_IDENT'    => $field_ident,
 280                  'PROFILE_FIELD_TYPE'    => $field_data['field_type'],
 281                  'PROFILE_FIELD_NAME'    => $profile_field->get_field_name($field_data['lang_name']),
 282                  'PROFILE_FIELD_EXPLAIN'    => $this->user->lang($field_data['lang_explain']),
 283              );
 284          }
 285  
 286          $profile_cache = $this->profile_cache;
 287  
 288          /**
 289          * Event to modify template headlines of the generated profile fields
 290          *
 291          * @event core.generate_profile_fields_template_headlines
 292          * @var    string    restrict_option    Restrict the published fields to a certain profile field option
 293          * @var    array    tpl_fields        Array with template data fields
 294          * @var    array    profile_cache    A copy of the profile cache to make additional checks
 295          * @since 3.1.6-RC1
 296          */
 297          $vars = array(
 298              'restrict_option',
 299              'tpl_fields',
 300              'profile_cache',
 301          );
 302          extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_headlines', compact($vars)));
 303          unset($profile_cache);
 304  
 305          return $tpl_fields;
 306      }
 307  
 308      /**
 309      * Grab the user specific profile fields data
 310      *
 311      * @param    int|array    $user_ids    Single user id or an array of ids
 312      * @return array        Users profile fields data
 313      */
 314  	public function grab_profile_fields_data($user_ids = 0)
 315      {
 316          if (!is_array($user_ids))
 317          {
 318              $user_ids = array($user_ids);
 319          }
 320  
 321          if (!sizeof($this->profile_cache))
 322          {
 323              $this->build_cache();
 324          }
 325  
 326          if (!sizeof($user_ids))
 327          {
 328              return array();
 329          }
 330  
 331          $sql = 'SELECT *
 332              FROM ' . $this->fields_data_table . '
 333              WHERE ' . $this->db->sql_in_set('user_id', array_map('intval', $user_ids));
 334          $result = $this->db->sql_query($sql);
 335  
 336          $field_data = array();
 337          while ($row = $this->db->sql_fetchrow($result))
 338          {
 339              $field_data[$row['user_id']] = $row;
 340          }
 341          $this->db->sql_freeresult($result);
 342  
 343          /**
 344          * Event to modify profile fields data retrieved from the database
 345          *
 346          * @event core.grab_profile_fields_data
 347          * @var    array    user_ids        Single user id or an array of ids
 348          * @var    array    field_data        Array with profile fields data
 349          * @since 3.1.0-b3
 350          */
 351          $vars = array('user_ids', 'field_data');
 352          extract($this->dispatcher->trigger_event('core.grab_profile_fields_data', compact($vars)));
 353  
 354          $user_fields = array();
 355  
 356          // Go through the fields in correct order
 357          foreach (array_keys($this->profile_cache) as $used_ident)
 358          {
 359              foreach ($field_data as $user_id => $row)
 360              {
 361                  $user_fields[$user_id][$used_ident]['value'] = $row['pf_' . $used_ident];
 362                  $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident];
 363              }
 364  
 365              foreach ($user_ids as $user_id)
 366              {
 367                  if (!isset($user_fields[$user_id][$used_ident]) && $this->profile_cache[$used_ident]['field_show_novalue'])
 368                  {
 369                      $user_fields[$user_id][$used_ident]['value'] = '';
 370                      $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident];
 371                  }
 372              }
 373          }
 374  
 375          return $user_fields;
 376      }
 377  
 378      /**
 379      * Assign the user's profile fields data to the template
 380      *
 381      * @param array    $profile_row        Array with users profile field data
 382      * @param bool    $use_contact_fields    Should we display contact fields as such?
 383      *            This requires special treatments (links should not be parsed in the values, and more)
 384      * @return array
 385      */
 386  	public function generate_profile_fields_template_data($profile_row, $use_contact_fields = true)
 387      {
 388          // $profile_row == $user_fields[$row['user_id']];
 389          $tpl_fields = array();
 390          $tpl_fields['row'] = $tpl_fields['blockrow'] = array();
 391  
 392          /**
 393          * Event to modify data of the generated profile fields, before the template assignment loop
 394          *
 395          * @event core.generate_profile_fields_template_data_before
 396          * @var    array    profile_row        Array with users profile field data
 397          * @var    array    tpl_fields        Array with template data fields
 398          * @var    bool    use_contact_fields    Should we display contact fields as such?
 399          * @since 3.1.0-b3
 400          */
 401          $vars = array('profile_row', 'tpl_fields', 'use_contact_fields');
 402          extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_data_before', compact($vars)));
 403  
 404          foreach ($profile_row as $ident => $ident_ary)
 405          {
 406              $profile_field = $this->type_collection[$ident_ary['data']['field_type']];
 407              $value = $profile_field->get_profile_value($ident_ary['value'], $ident_ary['data']);
 408              $value_raw = $profile_field->get_profile_value_raw($ident_ary['value'], $ident_ary['data']);
 409  
 410              if ($value === null)
 411              {
 412                  continue;
 413              }
 414  
 415              $field_desc = $contact_url = '';
 416              if ($use_contact_fields && $ident_ary['data']['field_is_contact'])
 417              {
 418                  $value = $profile_field->get_profile_contact_value($ident_ary['value'], $ident_ary['data']);
 419                  $field_desc = $this->user->lang($ident_ary['data']['field_contact_desc']);
 420                  if (strpos($field_desc, '%s') !== false)
 421                  {
 422                      $field_desc = sprintf($field_desc, $value);
 423                  }
 424                  $contact_url = '';
 425                  if (strpos($ident_ary['data']['field_contact_url'], '%s') !== false)
 426                  {
 427                      $contact_url = sprintf($ident_ary['data']['field_contact_url'], $value);
 428                  }
 429              }
 430  
 431              $tpl_fields['row'] += array(
 432                  'PROFILE_' . strtoupper($ident) . '_IDENT'        => $ident,
 433                  'PROFILE_' . strtoupper($ident) . '_VALUE'        => $value,
 434                  'PROFILE_' . strtoupper($ident) . '_VALUE_RAW'    => $value_raw,
 435                  'PROFILE_' . strtoupper($ident) . '_CONTACT'    => $contact_url,
 436                  'PROFILE_' . strtoupper($ident) . '_DESC'        => $field_desc,
 437                  'PROFILE_' . strtoupper($ident) . '_TYPE'        => $ident_ary['data']['field_type'],
 438                  'PROFILE_' . strtoupper($ident) . '_NAME'        => $this->user->lang($ident_ary['data']['lang_name']),
 439                  'PROFILE_' . strtoupper($ident) . '_EXPLAIN'    => $this->user->lang($ident_ary['data']['lang_explain']),
 440  
 441                  'S_PROFILE_' . strtoupper($ident) . '_CONTACT'    => $ident_ary['data']['field_is_contact'],
 442                  'S_PROFILE_' . strtoupper($ident)            => true,
 443              );
 444  
 445              $tpl_fields['blockrow'][] = array(
 446                  'PROFILE_FIELD_IDENT'        => $ident,
 447                  'PROFILE_FIELD_VALUE'        => $value,
 448                  'PROFILE_FIELD_VALUE_RAW'    => $value_raw,
 449                  'PROFILE_FIELD_CONTACT'        => $contact_url,
 450                  'PROFILE_FIELD_DESC'        => $field_desc,
 451                  'PROFILE_FIELD_TYPE'        => $ident_ary['data']['field_type'],
 452                  'PROFILE_FIELD_NAME'        => $this->user->lang($ident_ary['data']['lang_name']),
 453                  'PROFILE_FIELD_EXPLAIN'        => $this->user->lang($ident_ary['data']['lang_explain']),
 454  
 455                  'S_PROFILE_CONTACT'                        => $ident_ary['data']['field_is_contact'],
 456                  'S_PROFILE_' . strtoupper($ident)        => true,
 457              );
 458          }
 459  
 460          /**
 461          * Event to modify template data of the generated profile fields
 462          *
 463          * @event core.generate_profile_fields_template_data
 464          * @var    array    profile_row        Array with users profile field data
 465          * @var    array    tpl_fields        Array with template data fields
 466          * @var    bool    use_contact_fields    Should we display contact fields as such?
 467          * @since 3.1.0-b3
 468          */
 469          $vars = array('profile_row', 'tpl_fields', 'use_contact_fields');
 470          extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_data', compact($vars)));
 471  
 472          return $tpl_fields;
 473      }
 474  
 475      /**
 476      * Build Array for user insertion into custom profile fields table
 477      */
 478  	public function build_insert_sql_array($cp_data)
 479      {
 480          $sql_not_in = array();
 481          foreach ($cp_data as $key => $null)
 482          {
 483              $sql_not_in[] = (strncmp($key, 'pf_', 3) === 0) ? substr($key, 3) : $key;
 484          }
 485  
 486          $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value
 487              FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f
 488              WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . '
 489                  ' . ((sizeof($sql_not_in)) ? ' AND ' . $this->db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . '
 490                  AND l.field_id = f.field_id';
 491          $result = $this->db->sql_query($sql);
 492  
 493          while ($row = $this->db->sql_fetchrow($result))
 494          {
 495              $profile_field = $this->type_collection[$row['field_type']];
 496              $cp_data['pf_' . $row['field_ident']] = $profile_field->get_default_field_value($row);
 497          }
 498          $this->db->sql_freeresult($result);
 499  
 500          return $cp_data;
 501      }
 502  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1