2020-01-26 13:59:30 +01:00
< ? php
2020-02-22 18:14:36 +01:00
/**
* This file is part of Part - DB ( https :// github . com / Part - DB / Part - DB - symfony ) .
*
2022-11-29 22:28:53 +01:00
* Copyright ( C ) 2019 - 2022 Jan Böhmer ( https :// github . com / jbtronics )
2020-02-22 18:14:36 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
2020-02-01 16:17:20 +01:00
declare ( strict_types = 1 );
2020-01-26 13:59:30 +01:00
namespace App\Services\LogSystem ;
use App\Entity\LogSystem\AbstractLogEntry ;
use App\Entity\UserSystem\User ;
2023-04-07 22:44:59 +02:00
use App\Services\Misc\ConsoleInfoHelper ;
2020-01-26 13:59:30 +01:00
use Doctrine\ORM\EntityManagerInterface ;
use Symfony\Component\Security\Core\Security ;
class EventLogger
{
2022-09-18 22:59:31 +02:00
protected int $minimum_log_level ;
protected array $blacklist ;
protected array $whitelist ;
protected EntityManagerInterface $em ;
protected Security $security ;
2023-04-07 22:44:59 +02:00
protected ConsoleInfoHelper $console_info_helper ;
2020-01-26 13:59:30 +01:00
2023-04-07 22:44:59 +02:00
public function __construct ( int $minimum_log_level , array $blacklist , array $whitelist , EntityManagerInterface $em ,
Security $security , ConsoleInfoHelper $console_info_helper )
2020-01-26 13:59:30 +01:00
{
$this -> minimum_log_level = $minimum_log_level ;
$this -> blacklist = $blacklist ;
$this -> whitelist = $whitelist ;
$this -> em = $em ;
$this -> security = $security ;
2023-04-07 22:44:59 +02:00
$this -> console_info_helper = $console_info_helper ;
2020-01-26 13:59:30 +01:00
}
/**
* Adds the given log entry to the Log , if the entry fullfills the global configured criterias .
* The change will not be flushed yet .
2020-02-01 16:17:20 +01:00
*
2020-08-21 21:36:22 +02:00
* @ return bool returns true , if the event was added to log
2020-01-26 13:59:30 +01:00
*/
public function log ( AbstractLogEntry $logEntry ) : bool
{
$user = $this -> security -> getUser ();
//If the user is not specified explicitly, set it to the current user
2020-02-01 16:17:20 +01:00
if (( null === $user || $user instanceof User ) && null === $logEntry -> getUser ()) {
if ( null === $user ) {
2020-01-26 13:59:30 +01:00
$repo = $this -> em -> getRepository ( User :: class );
$user = $repo -> getAnonymousUser ();
}
2020-02-03 13:33:15 +01:00
//If no anonymous user is available skip the log (needed for data fixtures)
if ( null === $user ) {
return false ;
}
2020-01-26 13:59:30 +01:00
$logEntry -> setUser ( $user );
}
2023-04-07 22:44:59 +02:00
//Set the console user info, if the log entry was created in a console command
if ( $this -> console_info_helper -> isCLI ()) {
2023-04-08 01:13:13 +02:00
$logEntry -> setCLIUsername ( $this -> console_info_helper -> getCLIUser () ? ? 'Unknown' );
2023-04-07 22:44:59 +02:00
}
2020-01-26 13:59:30 +01:00
if ( $this -> shouldBeAdded ( $logEntry )) {
$this -> em -> persist ( $logEntry );
2020-02-01 16:17:20 +01:00
2020-01-26 13:59:30 +01:00
return true ;
}
return false ;
}
2023-01-24 22:55:03 +01:00
/**
* Same as log (), but this function can be safely called from within the onFlush () doctrine event , as it
* updated the changesets of the unit of work .
* @ param AbstractLogEntry $logEntry
* @ return bool
*/
public function logFromOnFlush ( AbstractLogEntry $logEntry ) : bool
{
if ( $this -> log ( $logEntry )) {
$uow = $this -> em -> getUnitOfWork ();
//As we call it from onFlush, we have to recompute the changeset here, according to https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/events.html#reference-events-on-flush
$uow -> computeChangeSet ( $this -> em -> getClassMetadata ( get_class ( $logEntry )), $logEntry );
return true ;
}
//If the normal log function does not added the log entry, we just do nothing
return false ;
}
2020-01-26 13:59:30 +01:00
/**
* Adds the given log entry to the Log , if the entry fullfills the global configured criterias and flush afterwards .
2020-02-01 16:17:20 +01:00
*
2020-08-21 21:36:22 +02:00
* @ return bool returns true , if the event was added to log
2020-01-26 13:59:30 +01:00
*/
public function logAndFlush ( AbstractLogEntry $logEntry ) : bool
{
$tmp = $this -> log ( $logEntry );
$this -> em -> flush ();
2020-02-01 16:17:20 +01:00
2020-01-26 13:59:30 +01:00
return $tmp ;
}
public function shouldBeAdded (
AbstractLogEntry $logEntry ,
? int $minimum_log_level = null ,
? array $blacklist = null ,
? array $whitelist = null
) : bool {
//Apply the global settings, if nothing was specified
$minimum_log_level = $minimum_log_level ? ? $this -> minimum_log_level ;
$blacklist = $blacklist ? ? $this -> blacklist ;
$whitelist = $whitelist ? ? $this -> whitelist ;
//Dont add the entry if it does not reach the minimum level
if ( $logEntry -> getLevel () > $minimum_log_level ) {
return false ;
}
//Check if the event type is black listed
2020-08-21 21:36:22 +02:00
if ( ! empty ( $blacklist ) && $this -> isObjectClassInArray ( $logEntry , $blacklist )) {
2020-01-26 13:59:30 +01:00
return false ;
}
//Check for whitelisting
2020-08-21 21:36:22 +02:00
if ( ! empty ( $whitelist ) && ! $this -> isObjectClassInArray ( $logEntry , $whitelist )) {
2020-01-26 13:59:30 +01:00
return false ;
}
// By default all things should be added
return true ;
}
/**
2020-02-01 16:17:20 +01:00
* Check if the object type is given in the classes array . This also works for inherited types .
*
* @ param object $object The object which should be checked
2020-08-21 21:36:22 +02:00
* @ param string [] $classes the list of class names that should be used for checking
2020-01-26 13:59:30 +01:00
*/
protected function isObjectClassInArray ( object $object , array $classes ) : bool
{
//Check if the class is directly in the classes array
2020-02-01 16:17:20 +01:00
if ( in_array ( get_class ( $object ), $classes , true )) {
2020-01-26 13:59:30 +01:00
return true ;
}
//Iterate over all classes and check for inheritance
foreach ( $classes as $class ) {
if ( is_a ( $object , $class )) {
return true ;
}
}
return false ;
}
2020-02-01 16:17:20 +01:00
}