[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Plugin 5 * @subpackage Actionlog.joomla 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\Plugin\Actionlog\Joomla\Extension; 12 13 use Joomla\CMS\Component\ComponentHelper; 14 use Joomla\CMS\Factory; 15 use Joomla\CMS\Installer\Installer; 16 use Joomla\CMS\MVC\Factory\MVCFactoryServiceInterface; 17 use Joomla\CMS\Table\Table; 18 use Joomla\CMS\User\User; 19 use Joomla\Component\Actionlogs\Administrator\Helper\ActionlogsHelper; 20 use Joomla\Component\Actionlogs\Administrator\Plugin\ActionLogPlugin; 21 use Joomla\Database\DatabaseAwareTrait; 22 use Joomla\Database\Exception\ExecutionFailureException; 23 use Joomla\Event\DispatcherInterface; 24 use Joomla\Utilities\ArrayHelper; 25 use RuntimeException; 26 use stdClass; 27 28 // phpcs:disable PSR1.Files.SideEffects 29 \defined('_JEXEC') or die; 30 // phpcs:enable PSR1.Files.SideEffects 31 32 /** 33 * Joomla! Users Actions Logging Plugin. 34 * 35 * @since 3.9.0 36 */ 37 final class Joomla extends ActionLogPlugin 38 { 39 use DatabaseAwareTrait; 40 41 /** 42 * Array of loggable extensions. 43 * 44 * @var array 45 * @since 3.9.0 46 */ 47 protected $loggableExtensions = []; 48 49 /** 50 * Context aliases 51 * 52 * @var array 53 * @since 3.9.0 54 */ 55 protected $contextAliases = ['com_content.form' => 'com_content.article']; 56 57 /** 58 * Flag for loggable Api. 59 * 60 * @var boolean 61 * @since 4.0.0 62 */ 63 protected $loggableApi = false; 64 65 /** 66 * Array of loggable verbs. 67 * 68 * @var array 69 * @since 4.0.0 70 */ 71 protected $loggableVerbs = []; 72 73 /** 74 * Constructor. 75 * 76 * @param DispatcherInterface $dispatcher The dispatcher 77 * @param array $config An optional associative array of configuration settings 78 * 79 * @since 3.9.0 80 */ 81 public function __construct(DispatcherInterface $dispatcher, array $config) 82 { 83 parent::__construct($dispatcher, $config); 84 85 $params = ComponentHelper::getComponent('com_actionlogs')->getParams(); 86 87 $this->loggableExtensions = $params->get('loggable_extensions', []); 88 89 $this->loggableApi = $params->get('loggable_api', 0); 90 91 $this->loggableVerbs = $params->get('loggable_verbs', []); 92 } 93 94 /** 95 * After save content logging method 96 * This method adds a record to #__action_logs contains (message, date, context, user) 97 * Method is called right after the content is saved 98 * 99 * @param string $context The context of the content passed to the plugin 100 * @param object $article A JTableContent object 101 * @param boolean $isNew If the content is just about to be created 102 * 103 * @return void 104 * 105 * @since 3.9.0 106 */ 107 public function onContentAfterSave($context, $article, $isNew): void 108 { 109 if (isset($this->contextAliases[$context])) { 110 $context = $this->contextAliases[$context]; 111 } 112 113 $params = $this->getActionLogParams($context); 114 115 // Not found a valid content type, don't process further 116 if ($params === null) { 117 return; 118 } 119 120 list($option, $contentType) = explode('.', $params->type_alias); 121 122 if (!$this->checkLoggable($option)) { 123 return; 124 } 125 126 if ($isNew) { 127 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_ADDED'; 128 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'; 129 } else { 130 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_UPDATED'; 131 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; 132 } 133 134 // If the content type doesn't have its own language key, use default language key 135 if (!$this->getApplication()->getLanguage()->hasKey($messageLanguageKey)) { 136 $messageLanguageKey = $defaultLanguageKey; 137 } 138 139 $id = empty($params->id_holder) ? 0 : $article->get($params->id_holder); 140 141 $message = array( 142 'action' => $isNew ? 'add' : 'update', 143 'type' => $params->text_prefix . '_TYPE_' . $params->type_title, 144 'id' => $id, 145 'title' => $article->get($params->title_holder), 146 'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $id, $params->id_holder, $article), 147 ); 148 149 $this->addLog(array($message), $messageLanguageKey, $context); 150 } 151 152 /** 153 * After delete content logging method 154 * This method adds a record to #__action_logs contains (message, date, context, user) 155 * Method is called right after the content is deleted 156 * 157 * @param string $context The context of the content passed to the plugin 158 * @param object $article A JTableContent object 159 * 160 * @return void 161 * 162 * @since 3.9.0 163 */ 164 public function onContentAfterDelete($context, $article): void 165 { 166 $option = $this->getApplication()->input->get('option'); 167 168 if (!$this->checkLoggable($option)) { 169 return; 170 } 171 172 $params = $this->getActionLogParams($context); 173 174 // Not found a valid content type, don't process further 175 if ($params === null) { 176 return; 177 } 178 179 // If the content type has its own language key, use it, otherwise, use default language key 180 if ($this->getApplication()->getLanguage()->hasKey(strtoupper($params->text_prefix . '_' . $params->type_title . '_DELETED'))) { 181 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_DELETED'; 182 } else { 183 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; 184 } 185 186 $id = empty($params->id_holder) ? 0 : $article->get($params->id_holder); 187 188 $message = array( 189 'action' => 'delete', 190 'type' => $params->text_prefix . '_TYPE_' . $params->type_title, 191 'id' => $id, 192 'title' => $article->get($params->title_holder), 193 ); 194 195 $this->addLog(array($message), $messageLanguageKey, $context); 196 } 197 198 /** 199 * On content change status logging method 200 * This method adds a record to #__action_logs contains (message, date, context, user) 201 * Method is called when the status of the article is changed 202 * 203 * @param string $context The context of the content passed to the plugin 204 * @param array $pks An array of primary key ids of the content that has changed state. 205 * @param integer $value The value of the state that the content has been changed to. 206 * 207 * @return void 208 * 209 * @since 3.9.0 210 */ 211 public function onContentChangeState($context, $pks, $value) 212 { 213 $option = $this->getApplication()->input->getCmd('option'); 214 215 if (!$this->checkLoggable($option)) { 216 return; 217 } 218 219 $params = $this->getActionLogParams($context); 220 221 // Not found a valid content type, don't process further 222 if ($params === null) { 223 return; 224 } 225 226 list(, $contentType) = explode('.', $params->type_alias); 227 228 switch ($value) { 229 case 0: 230 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_UNPUBLISHED'; 231 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UNPUBLISHED'; 232 $action = 'unpublish'; 233 break; 234 case 1: 235 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_PUBLISHED'; 236 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_PUBLISHED'; 237 $action = 'publish'; 238 break; 239 case 2: 240 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_ARCHIVED'; 241 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ARCHIVED'; 242 $action = 'archive'; 243 break; 244 case -2: 245 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_TRASHED'; 246 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_TRASHED'; 247 $action = 'trash'; 248 break; 249 default: 250 $messageLanguageKey = ''; 251 $defaultLanguageKey = ''; 252 $action = ''; 253 break; 254 } 255 256 // If the content type doesn't have its own language key, use default language key 257 if (!$this->getApplication()->getLanguage()->hasKey($messageLanguageKey)) { 258 $messageLanguageKey = $defaultLanguageKey; 259 } 260 261 $db = $this->getDatabase(); 262 $query = $db->getQuery(true) 263 ->select($db->quoteName([$params->title_holder, $params->id_holder])) 264 ->from($db->quoteName($params->table_name)) 265 ->whereIn($db->quoteName($params->id_holder), ArrayHelper::toInteger($pks)); 266 $db->setQuery($query); 267 268 try { 269 $items = $db->loadObjectList($params->id_holder); 270 } catch (RuntimeException $e) { 271 $items = array(); 272 } 273 274 $messages = array(); 275 276 foreach ($pks as $pk) { 277 $message = array( 278 'action' => $action, 279 'type' => $params->text_prefix . '_TYPE_' . $params->type_title, 280 'id' => $pk, 281 'title' => $items[$pk]->{$params->title_holder}, 282 'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $pk, $params->id_holder, null), 283 ); 284 285 $messages[] = $message; 286 } 287 288 $this->addLog($messages, $messageLanguageKey, $context); 289 } 290 291 /** 292 * On Saving application configuration logging method 293 * Method is called when the application config is being saved 294 * 295 * @param \Joomla\Registry\Registry $config Registry object with the new config 296 * 297 * @return void 298 * 299 * @since 3.9.0 300 */ 301 public function onApplicationAfterSave($config): void 302 { 303 $option = $this->getApplication()->input->getCmd('option'); 304 305 if (!$this->checkLoggable($option)) { 306 return; 307 } 308 309 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_APPLICATION_CONFIG_UPDATED'; 310 $action = 'update'; 311 312 $message = array( 313 'action' => $action, 314 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_APPLICATION_CONFIG', 315 'extension_name' => 'com_config.application', 316 'itemlink' => 'index.php?option=com_config', 317 ); 318 319 $this->addLog(array($message), $messageLanguageKey, 'com_config.application'); 320 } 321 322 /** 323 * On installing extensions logging method 324 * This method adds a record to #__action_logs contains (message, date, context, user) 325 * Method is called when an extension is installed 326 * 327 * @param Installer $installer Installer object 328 * @param integer $eid Extension Identifier 329 * 330 * @return void 331 * 332 * @since 3.9.0 333 */ 334 public function onExtensionAfterInstall($installer, $eid) 335 { 336 $context = $this->getApplication()->input->get('option'); 337 338 if (!$this->checkLoggable($context)) { 339 return; 340 } 341 342 $manifest = $installer->get('manifest'); 343 344 if ($manifest === null) { 345 return; 346 } 347 348 $extensionType = $manifest->attributes()->type; 349 350 // If the extension type has its own language key, use it, otherwise, use default language key 351 if ($this->getApplication()->getLanguage()->hasKey(strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_INSTALLED'))) { 352 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_INSTALLED'; 353 } else { 354 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_INSTALLED'; 355 } 356 357 $message = array( 358 'action' => 'install', 359 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType, 360 'id' => $eid, 361 'name' => (string) $manifest->name, 362 'extension_name' => (string) $manifest->name, 363 ); 364 365 $this->addLog(array($message), $messageLanguageKey, $context); 366 } 367 368 /** 369 * On uninstalling extensions logging method 370 * This method adds a record to #__action_logs contains (message, date, context, user) 371 * Method is called when an extension is uninstalled 372 * 373 * @param Installer $installer Installer instance 374 * @param integer $eid Extension id 375 * @param integer $result Installation result 376 * 377 * @return void 378 * 379 * @since 3.9.0 380 */ 381 public function onExtensionAfterUninstall($installer, $eid, $result) 382 { 383 $context = $this->getApplication()->input->get('option'); 384 385 if (!$this->checkLoggable($context)) { 386 return; 387 } 388 389 // If the process failed, we don't have manifest data, stop process to avoid fatal error 390 if ($result === false) { 391 return; 392 } 393 394 $manifest = $installer->get('manifest'); 395 396 if ($manifest === null) { 397 return; 398 } 399 400 $extensionType = $manifest->attributes()->type; 401 402 // If the extension type has its own language key, use it, otherwise, use default language key 403 if ($this->getApplication()->getLanguage()->hasKey(strtoupper('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UNINSTALLED'))) { 404 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UNINSTALLED'; 405 } else { 406 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_UNINSTALLED'; 407 } 408 409 $message = array( 410 'action' => 'install', 411 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType, 412 'id' => $eid, 413 'name' => (string) $manifest->name, 414 'extension_name' => (string) $manifest->name, 415 ); 416 417 $this->addLog(array($message), $messageLanguageKey, $context); 418 } 419 420 /** 421 * On updating extensions logging method 422 * This method adds a record to #__action_logs contains (message, date, context, user) 423 * Method is called when an extension is updated 424 * 425 * @param Installer $installer Installer instance 426 * @param integer $eid Extension id 427 * 428 * @return void 429 * 430 * @since 3.9.0 431 */ 432 public function onExtensionAfterUpdate($installer, $eid) 433 { 434 $context = $this->getApplication()->input->get('option'); 435 436 if (!$this->checkLoggable($context)) { 437 return; 438 } 439 440 $manifest = $installer->get('manifest'); 441 442 if ($manifest === null) { 443 return; 444 } 445 446 $extensionType = $manifest->attributes()->type; 447 448 // If the extension type has its own language key, use it, otherwise, use default language key 449 if ($this->getApplication()->getLanguage()->hasKey('PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UPDATED')) { 450 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_' . $extensionType . '_UPDATED'; 451 } else { 452 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_UPDATED'; 453 } 454 455 $message = array( 456 'action' => 'update', 457 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_' . $extensionType, 458 'id' => $eid, 459 'name' => (string) $manifest->name, 460 'extension_name' => (string) $manifest->name, 461 ); 462 463 $this->addLog(array($message), $messageLanguageKey, $context); 464 } 465 466 /** 467 * On Saving extensions logging method 468 * Method is called when an extension is being saved 469 * 470 * @param string $context The extension 471 * @param Table $table DataBase Table object 472 * @param boolean $isNew If the extension is new or not 473 * 474 * @return void 475 * 476 * @since 3.9.0 477 */ 478 public function onExtensionAfterSave($context, $table, $isNew): void 479 { 480 $option = $this->getApplication()->input->getCmd('option'); 481 482 if ($table->get('module') != null) { 483 $option = 'com_modules'; 484 } 485 486 if (!$this->checkLoggable($option)) { 487 return; 488 } 489 490 $params = $this->getActionLogParams($context); 491 492 // Not found a valid content type, don't process further 493 if ($params === null) { 494 return; 495 } 496 497 list(, $contentType) = explode('.', $params->type_alias); 498 499 if ($isNew) { 500 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_ADDED'; 501 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'; 502 } else { 503 $messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_UPDATED'; 504 $defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; 505 } 506 507 // If the extension type doesn't have it own language key, use default language key 508 if (!$this->getApplication()->getLanguage()->hasKey($messageLanguageKey)) { 509 $messageLanguageKey = $defaultLanguageKey; 510 } 511 512 $message = array( 513 'action' => $isNew ? 'add' : 'update', 514 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_' . $params->type_title, 515 'id' => $table->get($params->id_holder), 516 'title' => $table->get($params->title_holder), 517 'extension_name' => $table->get($params->title_holder), 518 'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $table->get($params->id_holder), $params->id_holder), 519 ); 520 521 $this->addLog(array($message), $messageLanguageKey, $context); 522 } 523 524 /** 525 * On Deleting extensions logging method 526 * Method is called when an extension is being deleted 527 * 528 * @param string $context The extension 529 * @param Table $table DataBase Table object 530 * 531 * @return void 532 * 533 * @since 3.9.0 534 */ 535 public function onExtensionAfterDelete($context, $table): void 536 { 537 if (!$this->checkLoggable($this->getApplication()->input->get('option'))) { 538 return; 539 } 540 541 $params = $this->getActionLogParams($context); 542 543 // Not found a valid content type, don't process further 544 if ($params === null) { 545 return; 546 } 547 548 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; 549 550 $message = array( 551 'action' => 'delete', 552 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_' . $params->type_title, 553 'title' => $table->get($params->title_holder), 554 ); 555 556 $this->addLog(array($message), $messageLanguageKey, $context); 557 } 558 559 /** 560 * On saving user data logging method 561 * 562 * Method is called after user data is stored in the database. 563 * This method logs who created/edited any user's data 564 * 565 * @param array $user Holds the new user data. 566 * @param boolean $isnew True if a new user is stored. 567 * @param boolean $success True if user was successfully stored in the database. 568 * @param string $msg Message. 569 * 570 * @return void 571 * 572 * @since 3.9.0 573 */ 574 public function onUserAfterSave($user, $isnew, $success, $msg): void 575 { 576 $context = $this->getApplication()->input->get('option'); 577 $task = $this->getApplication()->input->post->get('task'); 578 579 if (!$this->checkLoggable($context)) { 580 return; 581 } 582 583 $jUser = Factory::getUser(); 584 585 if (!$jUser->id) { 586 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_REGISTERED'; 587 $action = 'register'; 588 589 // Reset request 590 if ($task === 'reset.request') { 591 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_RESET_REQUEST'; 592 $action = 'resetrequest'; 593 } 594 595 // Reset complete 596 if ($task === 'reset.complete') { 597 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_RESET_COMPLETE'; 598 $action = 'resetcomplete'; 599 } 600 601 // Registration Activation 602 if ($task === 'registration.activate') { 603 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_REGISTRATION_ACTIVATE'; 604 $action = 'activaterequest'; 605 } 606 } elseif ($isnew) { 607 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'; 608 $action = 'add'; 609 } else { 610 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; 611 $action = 'update'; 612 } 613 614 $userId = $jUser->id ?: $user['id']; 615 $username = $jUser->username ?: $user['username']; 616 617 $message = array( 618 'action' => $action, 619 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 620 'id' => $user['id'], 621 'title' => $user['name'], 622 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user['id'], 623 'userid' => $userId, 624 'username' => $username, 625 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, 626 ); 627 628 $this->addLog(array($message), $messageLanguageKey, $context, $userId); 629 } 630 631 /** 632 * On deleting user data logging method 633 * 634 * Method is called after user data is deleted from the database 635 * 636 * @param array $user Holds the user data 637 * @param boolean $success True if user was successfully stored in the database 638 * @param string $msg Message 639 * 640 * @return void 641 * 642 * @since 3.9.0 643 */ 644 public function onUserAfterDelete($user, $success, $msg): void 645 { 646 $context = $this->getApplication()->input->get('option'); 647 648 if (!$this->checkLoggable($context)) { 649 return; 650 } 651 652 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; 653 654 $message = array( 655 'action' => 'delete', 656 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 657 'id' => $user['id'], 658 'title' => $user['name'], 659 ); 660 661 $this->addLog(array($message), $messageLanguageKey, $context); 662 } 663 664 /** 665 * On after save user group data logging method 666 * 667 * Method is called after user group is stored into the database 668 * 669 * @param string $context The context 670 * @param Table $table DataBase Table object 671 * @param boolean $isNew Is new or not 672 * 673 * @return void 674 * 675 * @since 3.9.0 676 */ 677 public function onUserAfterSaveGroup($context, $table, $isNew): void 678 { 679 // Override context (com_users.group) with the component context (com_users) to pass the checkLoggable 680 $context = $this->getApplication()->input->get('option'); 681 682 if (!$this->checkLoggable($context)) { 683 return; 684 } 685 686 if ($isNew) { 687 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED'; 688 $action = 'add'; 689 } else { 690 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; 691 $action = 'update'; 692 } 693 694 $message = array( 695 'action' => $action, 696 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER_GROUP', 697 'id' => $table->id, 698 'title' => $table->title, 699 'itemlink' => 'index.php?option=com_users&task=group.edit&id=' . $table->id, 700 ); 701 702 $this->addLog(array($message), $messageLanguageKey, $context); 703 } 704 705 /** 706 * On deleting user group data logging method 707 * 708 * Method is called after user group is deleted from the database 709 * 710 * @param array $group Holds the group data 711 * @param boolean $success True if user was successfully stored in the database 712 * @param string $msg Message 713 * 714 * @return void 715 * 716 * @since 3.9.0 717 */ 718 public function onUserAfterDeleteGroup($group, $success, $msg): void 719 { 720 $context = $this->getApplication()->input->get('option'); 721 722 if (!$this->checkLoggable($context)) { 723 return; 724 } 725 726 $messageLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; 727 728 $message = array( 729 'action' => 'delete', 730 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER_GROUP', 731 'id' => $group['id'], 732 'title' => $group['title'], 733 ); 734 735 $this->addLog(array($message), $messageLanguageKey, $context); 736 } 737 738 /** 739 * Method to log user login success action 740 * 741 * @param array $options Array holding options (user, responseType) 742 * 743 * @return void 744 * 745 * @since 3.9.0 746 */ 747 public function onUserAfterLogin($options) 748 { 749 if ($options['action'] === 'core.login.api') { 750 return; 751 } 752 753 $context = 'com_users'; 754 755 if (!$this->checkLoggable($context)) { 756 return; 757 } 758 759 $loggedInUser = $options['user']; 760 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_LOGGED_IN'; 761 762 $message = array( 763 'action' => 'login', 764 'userid' => $loggedInUser->id, 765 'username' => $loggedInUser->username, 766 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $loggedInUser->id, 767 'app' => 'PLG_ACTIONLOG_JOOMLA_APPLICATION_' . $this->getApplication()->getName(), 768 ); 769 770 $this->addLog(array($message), $messageLanguageKey, $context, $loggedInUser->id); 771 } 772 773 /** 774 * Method to log user login failed action 775 * 776 * @param array $response Array of response data. 777 * 778 * @return void 779 * 780 * @since 3.9.0 781 */ 782 public function onUserLoginFailure($response) 783 { 784 $context = 'com_users'; 785 786 if (!$this->checkLoggable($context)) { 787 return; 788 } 789 790 // Get the user id for the given username 791 $db = $this->getDatabase(); 792 $query = $db->getQuery(true) 793 ->select($db->quoteName(['id', 'username'])) 794 ->from($db->quoteName('#__users')) 795 ->where($db->quoteName('username') . ' = :username') 796 ->bind(':username', $response['username']); 797 $db->setQuery($query); 798 799 try { 800 $loggedInUser = $db->loadObject(); 801 } catch (ExecutionFailureException $e) { 802 return; 803 } 804 805 // Not a valid user, return 806 if (!isset($loggedInUser->id)) { 807 return; 808 } 809 810 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED'; 811 812 $message = array( 813 'action' => 'login', 814 'id' => $loggedInUser->id, 815 'userid' => $loggedInUser->id, 816 'username' => $loggedInUser->username, 817 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $loggedInUser->id, 818 'app' => 'PLG_ACTIONLOG_JOOMLA_APPLICATION_' . $this->getApplication()->getName(), 819 ); 820 821 $this->addLog(array($message), $messageLanguageKey, $context, $loggedInUser->id); 822 } 823 824 /** 825 * Method to log user's logout action 826 * 827 * @param array $user Holds the user data 828 * @param array $options Array holding options (remember, autoregister, group) 829 * 830 * @return void 831 * 832 * @since 3.9.0 833 */ 834 public function onUserLogout($user, $options = array()) 835 { 836 $context = 'com_users'; 837 838 if (!$this->checkLoggable($context)) { 839 return; 840 } 841 842 $loggedOutUser = User::getInstance($user['id']); 843 844 if ($loggedOutUser->block) { 845 return; 846 } 847 848 $messageLanguageKey = 'PLG_ACTIONLOG_JOOMLA_USER_LOGGED_OUT'; 849 850 $message = array( 851 'action' => 'logout', 852 'id' => $loggedOutUser->id, 853 'userid' => $loggedOutUser->id, 854 'username' => $loggedOutUser->username, 855 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $loggedOutUser->id, 856 'app' => 'PLG_ACTIONLOG_JOOMLA_APPLICATION_' . $this->getApplication()->getName(), 857 ); 858 859 $this->addLog(array($message), $messageLanguageKey, $context); 860 } 861 862 /** 863 * Function to check if a component is loggable or not 864 * 865 * @param string $extension The extension that triggered the event 866 * 867 * @return boolean 868 * 869 * @since 3.9.0 870 */ 871 protected function checkLoggable($extension) 872 { 873 return in_array($extension, $this->loggableExtensions); 874 } 875 876 /** 877 * On after Remind username request 878 * 879 * Method is called after user request to remind their username. 880 * 881 * @param array $user Holds the user data. 882 * 883 * @return void 884 * 885 * @since 3.9.0 886 */ 887 public function onUserAfterRemind($user) 888 { 889 $context = $this->getApplication()->input->get('option'); 890 891 if (!$this->checkLoggable($context)) { 892 return; 893 } 894 895 $message = array( 896 'action' => 'remind', 897 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 898 'id' => $user->id, 899 'title' => $user->name, 900 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 901 'userid' => $user->id, 902 'username' => $user->name, 903 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 904 ); 905 906 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_USER_REMIND', $context, $user->id); 907 } 908 909 /** 910 * On after Check-in request 911 * 912 * Method is called after user request to check-in items. 913 * 914 * @param array $table Holds the table name. 915 * 916 * @return void 917 * 918 * @since 3.9.3 919 */ 920 public function onAfterCheckin($table) 921 { 922 $context = 'com_checkin'; 923 $user = Factory::getUser(); 924 925 if (!$this->checkLoggable($context)) { 926 return; 927 } 928 929 $message = array( 930 'action' => 'checkin', 931 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 932 'id' => $user->id, 933 'title' => $user->username, 934 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 935 'userid' => $user->id, 936 'username' => $user->username, 937 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 938 'table' => str_replace($this->getDatabase()->getPrefix(), '#__', $table), 939 ); 940 941 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_USER_CHECKIN', $context, $user->id); 942 } 943 944 /** 945 * On after log action purge 946 * 947 * Method is called after user request to clean action log items. 948 * 949 * @param array $group Holds the group name. 950 * 951 * @return void 952 * 953 * @since 3.9.4 954 */ 955 public function onAfterLogPurge($group = '') 956 { 957 $context = $this->getApplication()->input->get('option'); 958 $user = Factory::getUser(); 959 $message = array( 960 'action' => 'actionlogs', 961 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 962 'id' => $user->id, 963 'title' => $user->username, 964 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 965 'userid' => $user->id, 966 'username' => $user->username, 967 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 968 ); 969 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_USER_LOG', $context, $user->id); 970 } 971 972 /** 973 * On after log export 974 * 975 * Method is called after user request to export action log items. 976 * 977 * @param array $group Holds the group name. 978 * 979 * @return void 980 * 981 * @since 3.9.4 982 */ 983 public function onAfterLogExport($group = '') 984 { 985 $context = $this->getApplication()->input->get('option'); 986 $user = Factory::getUser(); 987 $message = array( 988 'action' => 'actionlogs', 989 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 990 'id' => $user->id, 991 'title' => $user->username, 992 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 993 'userid' => $user->id, 994 'username' => $user->username, 995 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 996 ); 997 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_USER_LOGEXPORT', $context, $user->id); 998 } 999 1000 /** 1001 * On after Cache purge 1002 * 1003 * Method is called after user request to clean cached items. 1004 * 1005 * @param string $group Holds the group name. 1006 * 1007 * @return void 1008 * 1009 * @since 3.9.4 1010 */ 1011 public function onAfterPurge($group = 'all') 1012 { 1013 $context = $this->getApplication()->input->get('option'); 1014 $user = Factory::getUser(); 1015 1016 if (!$this->checkLoggable($context)) { 1017 return; 1018 } 1019 1020 $message = array( 1021 'action' => 'cache', 1022 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 1023 'id' => $user->id, 1024 'title' => $user->username, 1025 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 1026 'userid' => $user->id, 1027 'username' => $user->username, 1028 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 1029 'group' => $group, 1030 ); 1031 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_USER_CACHE', $context, $user->id); 1032 } 1033 1034 /** 1035 * On after Api dispatched 1036 * 1037 * Method is called after user perform an API request better on onAfterDispatch. 1038 * 1039 * @return void 1040 * 1041 * @since 4.0.0 1042 */ 1043 public function onAfterDispatch() 1044 { 1045 if (!$this->getApplication()->isClient('api')) { 1046 return; 1047 } 1048 1049 if ($this->loggableApi === 0) { 1050 return; 1051 } 1052 1053 $verb = $this->getApplication()->input->getMethod(); 1054 1055 if (!in_array($verb, $this->loggableVerbs)) { 1056 return; 1057 } 1058 1059 $context = $this->getApplication()->input->get('option'); 1060 1061 if (!$this->checkLoggable($context)) { 1062 return; 1063 } 1064 1065 $user = $this->getApplication()->getIdentity(); 1066 $message = array( 1067 'action' => 'API', 1068 'verb' => $verb, 1069 'username' => $user->username, 1070 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 1071 'url' => htmlspecialchars(urldecode($this->getApplication()->get('uri.route')), ENT_QUOTES, 'UTF-8'), 1072 ); 1073 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_API', $context, $user->id); 1074 } 1075 1076 /** 1077 * On after CMS Update 1078 * 1079 * Method is called after user update the CMS. 1080 * 1081 * @param string $oldVersion The Joomla version before the update 1082 * 1083 * @return void 1084 * 1085 * @since 3.9.21 1086 */ 1087 public function onJoomlaAfterUpdate($oldVersion = null) 1088 { 1089 $context = $this->getApplication()->input->get('option'); 1090 $user = Factory::getUser(); 1091 1092 if (empty($oldVersion)) { 1093 $oldVersion = $this->getApplication()->getLanguage()->_('JLIB_UNKNOWN'); 1094 } 1095 1096 $message = array( 1097 'action' => 'joomlaupdate', 1098 'type' => 'PLG_ACTIONLOG_JOOMLA_TYPE_USER', 1099 'id' => $user->id, 1100 'title' => $user->username, 1101 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 1102 'userid' => $user->id, 1103 'username' => $user->username, 1104 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, 1105 'version' => JVERSION, 1106 'oldversion' => $oldVersion, 1107 ); 1108 $this->addLog(array($message), 'PLG_ACTIONLOG_JOOMLA_USER_UPDATE', $context, $user->id); 1109 } 1110 1111 /** 1112 * Returns the action log params for the given context. 1113 * 1114 * @param string $context The context of the action log 1115 * 1116 * @return stdClass The params 1117 * 1118 * @since 4.2.0 1119 */ 1120 private function getActionLogParams($context): ?stdClass 1121 { 1122 $component = $this->getApplication()->bootComponent('actionlogs'); 1123 1124 if (!$component instanceof MVCFactoryServiceInterface) { 1125 return null; 1126 } 1127 1128 return $component->getMVCFactory()->createModel('ActionlogConfig', 'Administrator')->getLogContentTypeParams($context); 1129 } 1130 }
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 |