Spaces:
No application file
No application file
namespace Mautic\ConfigBundle\Service; | |
use Mautic\CoreBundle\Helper\IpLookupHelper; | |
use Mautic\CoreBundle\Model\AuditLogModel; | |
use Symfony\Component\HttpFoundation\File\UploadedFile; | |
/** | |
* Compare normalized for data and log changes. | |
*/ | |
class ConfigChangeLogger | |
{ | |
/** | |
* Keys to remove from log. | |
* | |
* @var string[] | |
*/ | |
private array $filterKeys = [ | |
'transifex_password', | |
'mailer_is_owner', | |
]; | |
/** | |
* @var mixed[]|null | |
*/ | |
private ?array $originalNormData = null; | |
public function __construct( | |
private IpLookupHelper $ipLookupHelper, | |
private AuditLogModel $auditLogModel | |
) { | |
} | |
/** | |
* @return ConfigChangeLogger | |
*/ | |
public function setOriginalNormData(array $originalNormData) | |
{ | |
$this->originalNormData = $originalNormData; | |
return $this; | |
} | |
/** | |
* Log changes if something was changed. | |
* Diff is based on form normalized data before and after post. | |
* | |
* @see Form::getNormData() | |
*/ | |
public function log(array $postNormData): void | |
{ | |
if (null === $this->originalNormData) { | |
throw new \RuntimeException('Set original normalized data at first'); | |
} | |
$originalData = $this->normalizeData($this->originalNormData); | |
$postData = $this->filterData($this->normalizeData($postNormData)); | |
$diff = []; | |
foreach ($postData as $key => $value) { | |
if (array_key_exists($key, $originalData) && $originalData[$key] != $value) { | |
if ($value instanceof UploadedFile) { | |
$value = $value->getFilename(); | |
} | |
$diff[$key] = $value; | |
} | |
} | |
if (empty($diff)) { | |
return; | |
} | |
$log = [ | |
'bundle' => 'config', | |
'object' => 'config', | |
'objectId' => 0, | |
'action' => 'update', | |
'details' => $diff, | |
'ipAddress' => $this->ipLookupHelper->getIpAddressFromRequest(), | |
]; | |
$this->auditLogModel->writeToLog($log); | |
} | |
/** | |
* Some form data (AssetBundle) has 'parameters' inside array too. | |
* Normalize all. | |
*/ | |
private function normalizeData(array $data): array | |
{ | |
$key = 'parameters'; | |
$normData = []; | |
foreach ($data as $values) { | |
if (array_key_exists($key, $values)) { | |
$normData = array_merge($normData, $values[$key]); | |
} else { | |
$normData = array_merge($normData, $values); | |
} | |
} | |
return $normData; | |
} | |
/** | |
* Filter unused keys from post data. | |
*/ | |
private function filterData(array $data): array | |
{ | |
$keys = $this->filterKeys; | |
return array_filter($data, fn ($key): bool => !in_array($key, $keys), | |
ARRAY_FILTER_USE_KEY); | |
} | |
} | |