[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |