[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_privacy/src/Model/ -> RequestModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_privacy
   6   *
   7   * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Component\Privacy\Administrator\Model;
  12  
  13  use Joomla\CMS\Application\ApplicationHelper;
  14  use Joomla\CMS\Factory;
  15  use Joomla\CMS\Form\Form;
  16  use Joomla\CMS\Language\Language;
  17  use Joomla\CMS\Language\Text;
  18  use Joomla\CMS\Mail\Exception\MailDisabledException;
  19  use Joomla\CMS\Mail\MailTemplate;
  20  use Joomla\CMS\MVC\Model\AdminModel;
  21  use Joomla\CMS\Router\Route;
  22  use Joomla\CMS\Table\Table;
  23  use Joomla\CMS\Uri\Uri;
  24  use Joomla\CMS\User\User;
  25  use Joomla\CMS\User\UserHelper;
  26  use Joomla\Component\Actionlogs\Administrator\Model\ActionlogModel;
  27  use Joomla\Component\Privacy\Administrator\Table\RequestTable;
  28  use Joomla\Database\Exception\ExecutionFailureException;
  29  use PHPMailer\PHPMailer\Exception as phpmailerException;
  30  
  31  // phpcs:disable PSR1.Files.SideEffects
  32  \defined('_JEXEC') or die;
  33  // phpcs:enable PSR1.Files.SideEffects
  34  
  35  /**
  36   * Request item model class.
  37   *
  38   * @since  3.9.0
  39   */
  40  class RequestModel extends AdminModel
  41  {
  42      /**
  43       * Clean the cache
  44       *
  45       * @param   string  $group  The cache group
  46       *
  47       * @return  void
  48       *
  49       * @since   3.9.0
  50       */
  51      protected function cleanCache($group = 'com_privacy')
  52      {
  53          parent::cleanCache('com_privacy');
  54      }
  55  
  56      /**
  57       * Method for getting the form from the model.
  58       *
  59       * @param   array    $data      Data for the form.
  60       * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
  61       *
  62       * @return  Form|boolean  A Form object on success, false on failure
  63       *
  64       * @since   3.9.0
  65       */
  66      public function getForm($data = [], $loadData = true)
  67      {
  68          // Get the form.
  69          $form = $this->loadForm('com_privacy.request', 'request', ['control' => 'jform', 'load_data' => $loadData]);
  70  
  71          if (empty($form)) {
  72              return false;
  73          }
  74  
  75          return $form;
  76      }
  77  
  78      /**
  79       * Method to get a table object, load it if necessary.
  80       *
  81       * @param   string  $name     The table name. Optional.
  82       * @param   string  $prefix   The class prefix. Optional.
  83       * @param   array   $options  Configuration array for model. Optional.
  84       *
  85       * @return  Table  A Table object
  86       *
  87       * @throws  \Exception
  88       * @since   3.9.0
  89       */
  90      public function getTable($name = 'Request', $prefix = 'Administrator', $options = [])
  91      {
  92          return parent::getTable($name, $prefix, $options);
  93      }
  94  
  95      /**
  96       * Method to get the data that should be injected in the form.
  97       *
  98       * @return  array  The default data is an empty array.
  99       *
 100       * @since   3.9.0
 101       */
 102      protected function loadFormData()
 103      {
 104          // Check the session for previously entered form data.
 105          $data = Factory::getApplication()->getUserState('com_privacy.edit.request.data', []);
 106  
 107          if (empty($data)) {
 108              $data = $this->getItem();
 109          }
 110  
 111          return $data;
 112      }
 113  
 114      /**
 115       * Log the completion of a request to the action log system.
 116       *
 117       * @param   integer  $id  The ID of the request to process.
 118       *
 119       * @return  boolean
 120       *
 121       * @since   3.9.0
 122       */
 123      public function logRequestCompleted($id)
 124      {
 125          /** @var RequestTable $table */
 126          $table = $this->getTable();
 127  
 128          if (!$table->load($id)) {
 129              $this->setError($table->getError());
 130  
 131              return false;
 132          }
 133  
 134          $user = Factory::getUser();
 135  
 136          $message = [
 137              'action'       => 'request-completed',
 138              'requesttype'  => $table->request_type,
 139              'subjectemail' => $table->email,
 140              'id'           => $table->id,
 141              'itemlink'     => 'index.php?option=com_privacy&view=request&id=' . $table->id,
 142              'userid'       => $user->id,
 143              'username'     => $user->username,
 144              'accountlink'  => 'index.php?option=com_users&task=user.edit&id=' . $user->id,
 145          ];
 146  
 147          $this->getActionlogModel()->addLog([$message], 'COM_PRIVACY_ACTION_LOG_ADMIN_COMPLETED_REQUEST', 'com_privacy.request', $user->id);
 148  
 149          return true;
 150      }
 151  
 152      /**
 153       * Log the creation of a request to the action log system.
 154       *
 155       * @param   integer  $id  The ID of the request to process.
 156       *
 157       * @return  boolean
 158       *
 159       * @since   3.9.0
 160       */
 161      public function logRequestCreated($id)
 162      {
 163          /** @var RequestTable $table */
 164          $table = $this->getTable();
 165  
 166          if (!$table->load($id)) {
 167              $this->setError($table->getError());
 168  
 169              return false;
 170          }
 171  
 172          $user = Factory::getUser();
 173  
 174          $message = [
 175              'action'       => 'request-created',
 176              'requesttype'  => $table->request_type,
 177              'subjectemail' => $table->email,
 178              'id'           => $table->id,
 179              'itemlink'     => 'index.php?option=com_privacy&view=request&id=' . $table->id,
 180              'userid'       => $user->id,
 181              'username'     => $user->username,
 182              'accountlink'  => 'index.php?option=com_users&task=user.edit&id=' . $user->id,
 183          ];
 184  
 185          $this->getActionlogModel()->addLog([$message], 'COM_PRIVACY_ACTION_LOG_ADMIN_CREATED_REQUEST', 'com_privacy.request', $user->id);
 186  
 187          return true;
 188      }
 189  
 190      /**
 191       * Log the invalidation of a request to the action log system.
 192       *
 193       * @param   integer  $id  The ID of the request to process.
 194       *
 195       * @return  boolean
 196       *
 197       * @since   3.9.0
 198       */
 199      public function logRequestInvalidated($id)
 200      {
 201          /** @var RequestTable $table */
 202          $table = $this->getTable();
 203  
 204          if (!$table->load($id)) {
 205              $this->setError($table->getError());
 206  
 207              return false;
 208          }
 209  
 210          $user = Factory::getUser();
 211  
 212          $message = [
 213              'action'       => 'request-invalidated',
 214              'requesttype'  => $table->request_type,
 215              'subjectemail' => $table->email,
 216              'id'           => $table->id,
 217              'itemlink'     => 'index.php?option=com_privacy&view=request&id=' . $table->id,
 218              'userid'       => $user->id,
 219              'username'     => $user->username,
 220              'accountlink'  => 'index.php?option=com_users&task=user.edit&id=' . $user->id,
 221          ];
 222  
 223          $this->getActionlogModel()->addLog([$message], 'COM_PRIVACY_ACTION_LOG_ADMIN_INVALIDATED_REQUEST', 'com_privacy.request', $user->id);
 224  
 225          return true;
 226      }
 227  
 228      /**
 229       * Notifies the user that an information request has been created by a site administrator.
 230       *
 231       * Because confirmation tokens are stored in the database as a hashed value, this method will generate a new confirmation token
 232       * for the request.
 233       *
 234       * @param   integer  $id  The ID of the request to process.
 235       *
 236       * @return  boolean
 237       *
 238       * @since   3.9.0
 239       */
 240      public function notifyUserAdminCreatedRequest($id)
 241      {
 242          /** @var RequestTable $table */
 243          $table = $this->getTable();
 244  
 245          if (!$table->load($id)) {
 246              $this->setError($table->getError());
 247  
 248              return false;
 249          }
 250  
 251          /*
 252           * If there is an associated user account, we will attempt to send this email in the user's preferred language.
 253           * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used
 254           * for translating all messages.
 255           *
 256           * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class.
 257           */
 258  
 259          $lang = Factory::getLanguage();
 260  
 261          $db = $this->getDatabase();
 262  
 263          $userId = (int) $db->setQuery(
 264              $db->getQuery(true)
 265                  ->select($db->quoteName('id'))
 266                  ->from($db->quoteName('#__users'))
 267                  ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(:email)')
 268                  ->bind(':email', $table->email)
 269                  ->setLimit(1)
 270          )->loadResult();
 271  
 272          if ($userId) {
 273              $receiver = User::getInstance($userId);
 274  
 275              /*
 276               * We don't know if the user has admin access, so we will check if they have an admin language in their parameters,
 277               * falling back to the site language, falling back to the currently active language
 278               */
 279  
 280              $langCode = $receiver->getParam('admin_language', '');
 281  
 282              if (!$langCode) {
 283                  $langCode = $receiver->getParam('language', $lang->getTag());
 284              }
 285  
 286              $lang = Language::getInstance($langCode, $lang->getDebug());
 287          }
 288  
 289          // Ensure the right language files have been loaded
 290          $lang->load('com_privacy', JPATH_ADMINISTRATOR)
 291              || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy');
 292  
 293          // Regenerate the confirmation token
 294          $token       = ApplicationHelper::getHash(UserHelper::genRandomPassword());
 295          $hashedToken = UserHelper::hashPassword($token);
 296  
 297          $table->confirm_token            = $hashedToken;
 298          $table->confirm_token_created_at = Factory::getDate()->toSql();
 299  
 300          try {
 301              $table->store();
 302          } catch (ExecutionFailureException $exception) {
 303              $this->setError($exception->getMessage());
 304  
 305              return false;
 306          }
 307  
 308          // The mailer can be set to either throw Exceptions or return boolean false, account for both
 309          try {
 310              $app = Factory::getApplication();
 311  
 312              $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE;
 313  
 314              $templateData = [
 315                  'sitename' => $app->get('sitename'),
 316                  'url'      => Uri::root(),
 317                  'tokenurl' => Route::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode, true),
 318                  'formurl'  => Route::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode, true),
 319                  'token'    => $token,
 320              ];
 321  
 322              switch ($table->request_type) {
 323                  case 'export':
 324                      $mailer = new MailTemplate('com_privacy.notification.admin.export', $app->getLanguage()->getTag());
 325  
 326                      break;
 327  
 328                  case 'remove':
 329                      $mailer = new MailTemplate('com_privacy.notification.admin.remove', $app->getLanguage()->getTag());
 330  
 331                      break;
 332  
 333                  default:
 334                      $this->setError(Text::_('COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE'));
 335  
 336                      return false;
 337              }
 338  
 339              $mailer->addTemplateData($templateData);
 340              $mailer->addRecipient($table->email);
 341  
 342              $mailer->send();
 343  
 344              return true;
 345          } catch (MailDisabledException | phpmailerException $exception) {
 346              $this->setError($exception->getMessage());
 347  
 348              return false;
 349          }
 350      }
 351  
 352      /**
 353       * Method to save the form data.
 354       *
 355       * @param   array  $data  The form data.
 356       *
 357       * @return  boolean  True on success, False on error.
 358       *
 359       * @since   3.9.0
 360       */
 361      public function save($data)
 362      {
 363          $table = $this->getTable();
 364          $key   = $table->getKeyName();
 365          $pk    = !empty($data[$key]) ? $data[$key] : (int) $this->getState($this->getName() . '.id');
 366  
 367          if (!$pk && !Factory::getApplication()->get('mailonline', 1)) {
 368              $this->setError(Text::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED'));
 369  
 370              return false;
 371          }
 372  
 373          return parent::save($data);
 374      }
 375  
 376      /**
 377       * Method to validate the form data.
 378       *
 379       * @param   Form    $form   The form to validate against.
 380       * @param   array   $data   The data to validate.
 381       * @param   string  $group  The name of the field group to validate.
 382       *
 383       * @return  array|boolean  Array of filtered data if valid, false otherwise.
 384       *
 385       * @see     \Joomla\CMS\Form\FormRule
 386       * @see     JFilterInput
 387       * @since   3.9.0
 388       */
 389      public function validate($form, $data, $group = null)
 390      {
 391          $validatedData = parent::validate($form, $data, $group);
 392  
 393          // If parent validation failed there's no point in doing our extended validation
 394          if ($validatedData === false) {
 395              return false;
 396          }
 397  
 398          // Make sure the status is always 0
 399          $validatedData['status'] = 0;
 400  
 401          // The user cannot create a request for their own account
 402          if (strtolower(Factory::getUser()->email) === strtolower($validatedData['email'])) {
 403              $this->setError(Text::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_FOR_SELF'));
 404  
 405              return false;
 406          }
 407  
 408          // Check for an active request for this email address
 409          $db = $this->getDatabase();
 410  
 411          $query = $db->getQuery(true)
 412              ->select('COUNT(id)')
 413              ->from($db->quoteName('#__privacy_requests'))
 414              ->where($db->quoteName('email') . ' = :email')
 415              ->where($db->quoteName('request_type') . ' = :requesttype')
 416              ->whereIn($db->quoteName('status'), [0, 1])
 417              ->bind(':email', $validatedData['email'])
 418              ->bind(':requesttype', $validatedData['request_type']);
 419  
 420          $activeRequestCount = (int) $db->setQuery($query)->loadResult();
 421  
 422          if ($activeRequestCount > 0) {
 423              $this->setError(Text::_('COM_PRIVACY_ERROR_ACTIVE_REQUEST_FOR_EMAIL'));
 424  
 425              return false;
 426          }
 427  
 428          return $validatedData;
 429      }
 430  
 431      /**
 432       * Method to fetch an instance of the action log model.
 433       *
 434       * @return  ActionlogModel
 435       *
 436       * @since   4.0.0
 437       */
 438      private function getActionlogModel(): ActionlogModel
 439      {
 440          return Factory::getApplication()->bootComponent('com_actionlogs')
 441              ->getMVCFactory()->createModel('Actionlog', 'Administrator', ['ignore_request' => true]);
 442      }
 443  }


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