[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/plugins/user/profile/ -> profile.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Plugin
   5   * @subpackage  User.profile
   6   *
   7   * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9  
  10   * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
  11   */
  12  
  13  use Joomla\CMS\Date\Date;
  14  use Joomla\CMS\Form\Form;
  15  use Joomla\CMS\Form\FormHelper;
  16  use Joomla\CMS\HTML\HTMLHelper;
  17  use Joomla\CMS\Language\Text;
  18  use Joomla\CMS\Plugin\CMSPlugin;
  19  use Joomla\CMS\String\PunycodeHelper;
  20  use Joomla\Database\ParameterType;
  21  use Joomla\Utilities\ArrayHelper;
  22  
  23  // phpcs:disable PSR1.Files.SideEffects
  24  \defined('_JEXEC') or die;
  25  // phpcs:enable PSR1.Files.SideEffects
  26  
  27  /**
  28   * An example custom profile plugin.
  29   *
  30   * @since  1.6
  31   */
  32  class PlgUserProfile extends CMSPlugin
  33  {
  34      /**
  35       * @var    \Joomla\CMS\Application\CMSApplication
  36       *
  37       * @since  4.0.0
  38       */
  39      protected $app;
  40  
  41      /**
  42       * @var    \Joomla\Database\DatabaseDriver
  43       *
  44       * @since  4.0.0
  45       */
  46      protected $db;
  47  
  48      /**
  49       * Load the language file on instantiation.
  50       *
  51       * @var    boolean
  52       *
  53       * @since  3.1
  54       */
  55      protected $autoloadLanguage = true;
  56  
  57      /**
  58       * Date of birth.
  59       *
  60       * @var    string
  61       *
  62       * @since  3.1
  63       */
  64      private $date = '';
  65  
  66      /**
  67       * Runs on content preparation
  68       *
  69       * @param   string  $context  The context for the data
  70       * @param   object  $data     An object containing the data for the form.
  71       *
  72       * @return  boolean
  73       *
  74       * @since   1.6
  75       */
  76      public function onContentPrepareData($context, $data)
  77      {
  78          // Check we are manipulating a valid form.
  79          if (!in_array($context, ['com_users.profile', 'com_users.user', 'com_users.registration'])) {
  80              return true;
  81          }
  82  
  83          if (is_object($data)) {
  84              $userId = $data->id ?? 0;
  85  
  86              if (!isset($data->profile) && $userId > 0) {
  87                  // Load the profile data from the database.
  88                  $db    = $this->db;
  89                  $query = $db->getQuery(true)
  90                      ->select(
  91                          [
  92                              $db->quoteName('profile_key'),
  93                              $db->quoteName('profile_value'),
  94                          ]
  95                      )
  96                      ->from($db->quoteName('#__user_profiles'))
  97                      ->where($db->quoteName('user_id') . ' = :userid')
  98                      ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('profile.%'))
  99                      ->order($db->quoteName('ordering'))
 100                      ->bind(':userid', $userId, ParameterType::INTEGER);
 101  
 102                  $db->setQuery($query);
 103                  $results = $db->loadRowList();
 104  
 105                  // Merge the profile data.
 106                  $data->profile = [];
 107  
 108                  foreach ($results as $v) {
 109                      $k = str_replace('profile.', '', $v[0]);
 110                      $data->profile[$k] = json_decode($v[1], true);
 111  
 112                      if ($data->profile[$k] === null) {
 113                          $data->profile[$k] = $v[1];
 114                      }
 115                  }
 116              }
 117  
 118              if (!HTMLHelper::isRegistered('users.url')) {
 119                  HTMLHelper::register('users.url', [__CLASS__, 'url']);
 120              }
 121  
 122              if (!HTMLHelper::isRegistered('users.calendar')) {
 123                  HTMLHelper::register('users.calendar', [__CLASS__, 'calendar']);
 124              }
 125  
 126              if (!HTMLHelper::isRegistered('users.tos')) {
 127                  HTMLHelper::register('users.tos', [__CLASS__, 'tos']);
 128              }
 129  
 130              if (!HTMLHelper::isRegistered('users.dob')) {
 131                  HTMLHelper::register('users.dob', [__CLASS__, 'dob']);
 132              }
 133          }
 134  
 135          return true;
 136      }
 137  
 138      /**
 139       * Returns an anchor tag generated from a given value
 140       *
 141       * @param   string  $value  URL to use
 142       *
 143       * @return  mixed|string
 144       */
 145      public static function url($value)
 146      {
 147          if (empty($value)) {
 148              return HTMLHelper::_('users.value', $value);
 149          } else {
 150              // Convert website URL to utf8 for display
 151              $value = PunycodeHelper::urlToUTF8(htmlspecialchars($value));
 152  
 153              if (strpos($value, 'http') === 0) {
 154                  return '<a href="' . $value . '">' . $value . '</a>';
 155              } else {
 156                  return '<a href="http://' . $value . '">' . $value . '</a>';
 157              }
 158          }
 159      }
 160  
 161      /**
 162       * Returns html markup showing a date picker
 163       *
 164       * @param   string  $value  valid date string
 165       *
 166       * @return  mixed
 167       */
 168      public static function calendar($value)
 169      {
 170          if (empty($value)) {
 171              return HTMLHelper::_('users.value', $value);
 172          } else {
 173              return HTMLHelper::_('date', $value, null, null);
 174          }
 175      }
 176  
 177      /**
 178       * Returns the date of birth formatted and calculated using server timezone.
 179       *
 180       * @param   string  $value  valid date string
 181       *
 182       * @return  mixed
 183       */
 184      public static function dob($value)
 185      {
 186          if (!$value) {
 187              return '';
 188          }
 189  
 190          return HTMLHelper::_('date', $value, Text::_('DATE_FORMAT_LC1'), false);
 191      }
 192  
 193      /**
 194       * Return the translated strings yes or no depending on the value
 195       *
 196       * @param   boolean  $value  input value
 197       *
 198       * @return  string
 199       */
 200      public static function tos($value)
 201      {
 202          if ($value) {
 203              return Text::_('JYES');
 204          } else {
 205              return Text::_('JNO');
 206          }
 207      }
 208  
 209      /**
 210       * Adds additional fields to the user editing form
 211       *
 212       * @param   Form   $form  The form to be altered.
 213       * @param   mixed  $data  The associated data for the form.
 214       *
 215       * @return  boolean
 216       *
 217       * @since   1.6
 218       */
 219      public function onContentPrepareForm(Form $form, $data)
 220      {
 221          // Check we are manipulating a valid form.
 222          $name = $form->getName();
 223  
 224          if (!in_array($name, ['com_users.user', 'com_users.profile', 'com_users.registration'])) {
 225              return true;
 226          }
 227  
 228          // Add the registration fields to the form.
 229          FormHelper::addFieldPrefix('Joomla\\Plugin\\User\\Profile\\Field');
 230          FormHelper::addFormPath(__DIR__ . '/forms');
 231          $form->loadFile('profile');
 232  
 233          $fields = [
 234              'address1',
 235              'address2',
 236              'city',
 237              'region',
 238              'country',
 239              'postal_code',
 240              'phone',
 241              'website',
 242              'favoritebook',
 243              'aboutme',
 244              'dob',
 245              'tos',
 246          ];
 247  
 248          $tosArticle = $this->params->get('register_tos_article');
 249          $tosEnabled = $this->params->get('register-require_tos', 0);
 250  
 251          // We need to be in the registration form and field needs to be enabled
 252          if ($name !== 'com_users.registration' || !$tosEnabled) {
 253              // We only want the TOS in the registration form
 254              $form->removeField('tos', 'profile');
 255          } else {
 256              // Push the TOS article ID into the TOS field.
 257              $form->setFieldAttribute('tos', 'article', $tosArticle, 'profile');
 258          }
 259  
 260          foreach ($fields as $field) {
 261              // Case using the users manager in admin
 262              if ($name === 'com_users.user') {
 263                  // Toggle whether the field is required.
 264                  if ($this->params->get('profile-require_' . $field, 1) > 0) {
 265                      $form->setFieldAttribute($field, 'required', ($this->params->get('profile-require_' . $field) == 2) ? 'required' : '', 'profile');
 266                  } elseif (
 267                      // Remove the field if it is disabled in registration and profile
 268                      $this->params->get('register-require_' . $field, 1) == 0
 269                      && $this->params->get('profile-require_' . $field, 1) == 0
 270                  ) {
 271                      $form->removeField($field, 'profile');
 272                  }
 273              } elseif ($name === 'com_users.registration') {
 274                  // Case registration
 275                  // Toggle whether the field is required.
 276                  if ($this->params->get('register-require_' . $field, 1) > 0) {
 277                      $form->setFieldAttribute($field, 'required', ($this->params->get('register-require_' . $field) == 2) ? 'required' : '', 'profile');
 278                  } else {
 279                      $form->removeField($field, 'profile');
 280                  }
 281              } elseif ($name === 'com_users.profile') {
 282                  // Case profile in site or admin
 283                  // Toggle whether the field is required.
 284                  if ($this->params->get('profile-require_' . $field, 1) > 0) {
 285                      $form->setFieldAttribute($field, 'required', ($this->params->get('profile-require_' . $field) == 2) ? 'required' : '', 'profile');
 286                  } else {
 287                      $form->removeField($field, 'profile');
 288                  }
 289              }
 290          }
 291  
 292          // Drop the profile form entirely if there aren't any fields to display.
 293          $remainingfields = $form->getGroup('profile');
 294  
 295          if (!count($remainingfields)) {
 296              $form->removeGroup('profile');
 297          }
 298  
 299          return true;
 300      }
 301  
 302      /**
 303       * Method is called before user data is stored in the database
 304       *
 305       * @param   array    $user   Holds the old user data.
 306       * @param   boolean  $isnew  True if a new user is stored.
 307       * @param   array    $data   Holds the new user data.
 308       *
 309       * @return  boolean
 310       *
 311       * @since   3.1
 312       * @throws  InvalidArgumentException on invalid date.
 313       */
 314      public function onUserBeforeSave($user, $isnew, $data)
 315      {
 316          // Check that the date is valid.
 317          if (!empty($data['profile']['dob'])) {
 318              try {
 319                  $date = new Date($data['profile']['dob']);
 320                  $this->date = $date->format('Y-m-d H:i:s');
 321              } catch (Exception $e) {
 322                  // Throw an exception if date is not valid.
 323                  throw new InvalidArgumentException(Text::_('PLG_USER_PROFILE_ERROR_INVALID_DOB'));
 324              }
 325  
 326              if (Date::getInstance('now') < $date) {
 327                  // Throw an exception if dob is greater than now.
 328                  throw new InvalidArgumentException(Text::_('PLG_USER_PROFILE_ERROR_INVALID_DOB_FUTURE_DATE'));
 329              }
 330          }
 331  
 332          // Check that the tos is checked if required ie only in registration from frontend.
 333          $task       = $this->app->input->getCmd('task');
 334          $option     = $this->app->input->getCmd('option');
 335          $tosEnabled = ($this->params->get('register-require_tos', 0) == 2);
 336  
 337          // Check that the tos is checked.
 338          if ($task === 'register' && $tosEnabled && $option === 'com_users' && !$data['profile']['tos']) {
 339              throw new InvalidArgumentException(Text::_('PLG_USER_PROFILE_FIELD_TOS_DESC_SITE'));
 340          }
 341  
 342          return true;
 343      }
 344  
 345      /**
 346       * Saves user profile data
 347       *
 348       * @param   array    $data    entered user data
 349       * @param   boolean  $isNew   true if this is a new user
 350       * @param   boolean  $result  true if saving the user worked
 351       * @param   string   $error   error message
 352       *
 353       * @return  void
 354       */
 355      public function onUserAfterSave($data, $isNew, $result, $error): void
 356      {
 357          $userId = ArrayHelper::getValue($data, 'id', 0, 'int');
 358  
 359          if ($userId && $result && isset($data['profile']) && count($data['profile'])) {
 360              $db = $this->db;
 361  
 362              // Sanitize the date
 363              if (!empty($data['profile']['dob'])) {
 364                  $data['profile']['dob'] = $this->date;
 365              }
 366  
 367              $keys = array_keys($data['profile']);
 368  
 369              foreach ($keys as &$key) {
 370                  $key = 'profile.' . $key;
 371              }
 372  
 373              $query = $db->getQuery(true)
 374                  ->delete($db->quoteName('#__user_profiles'))
 375                  ->where($db->quoteName('user_id') . ' = :userid')
 376                  ->whereIn($db->quoteName('profile_key'), $keys, ParameterType::STRING)
 377                  ->bind(':userid', $userId, ParameterType::INTEGER);
 378              $db->setQuery($query);
 379              $db->execute();
 380  
 381              $query->clear()
 382                  ->select($db->quoteName('ordering'))
 383                  ->from($db->quoteName('#__user_profiles'))
 384                  ->where($db->quoteName('user_id') . ' = :userid')
 385                  ->bind(':userid', $userId, ParameterType::INTEGER);
 386              $db->setQuery($query);
 387              $usedOrdering = $db->loadColumn();
 388  
 389              $order = 1;
 390              $query->clear()
 391                  ->insert($db->quoteName('#__user_profiles'));
 392  
 393              foreach ($data['profile'] as $k => $v) {
 394                  while (in_array($order, $usedOrdering)) {
 395                      $order++;
 396                  }
 397  
 398                  $query->values(
 399                      implode(
 400                          ',',
 401                          $query->bindArray(
 402                              [
 403                                  $userId,
 404                                  'profile.' . $k,
 405                                  json_encode($v),
 406                                  $order++,
 407                              ],
 408                              [
 409                                  ParameterType::INTEGER,
 410                                  ParameterType::STRING,
 411                                  ParameterType::STRING,
 412                                  ParameterType::INTEGER,
 413                              ]
 414                          )
 415                      )
 416                  );
 417              }
 418  
 419              $db->setQuery($query);
 420              $db->execute();
 421          }
 422      }
 423  
 424      /**
 425       * Remove all user profile information for the given user ID
 426       *
 427       * Method is called after user data is deleted from the database
 428       *
 429       * @param   array    $user     Holds the user data
 430       * @param   boolean  $success  True if user was successfully stored in the database
 431       * @param   string   $msg      Message
 432       *
 433       * @return  void
 434       */
 435      public function onUserAfterDelete($user, $success, $msg): void
 436      {
 437          if (!$success) {
 438              return;
 439          }
 440  
 441          $userId = ArrayHelper::getValue($user, 'id', 0, 'int');
 442  
 443          if ($userId) {
 444              $db = $this->db;
 445              $query = $db->getQuery(true)
 446                  ->delete($db->quoteName('#__user_profiles'))
 447                  ->where($db->quoteName('user_id') . ' = :userid')
 448                  ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('profile.%'))
 449                  ->bind(':userid', $userId, ParameterType::INTEGER);
 450  
 451              $db->setQuery($query);
 452              $db->execute();
 453          }
 454      }
 455  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer