ActionHistory interface
This commit is contained in:
@@ -292,6 +292,11 @@ class Binding implements BindingProcessor
|
||||
'Espo\\Tools\\Api\\Cors\\Helper',
|
||||
'Espo\\Tools\\Api\\Cors\\DefaultHelper'
|
||||
);
|
||||
|
||||
$binder->bindImplementation(
|
||||
'Espo\\Core\\Record\\ActionHistory\\ActionLogger',
|
||||
'Espo\\Core\\Record\\ActionHistory\\DefaultActionLogger'
|
||||
);
|
||||
}
|
||||
|
||||
private function bindAcl(Binder $binder): void
|
||||
|
||||
@@ -35,10 +35,10 @@ use Espo\Core\Action\Params;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Core\ORM\EntityManager;
|
||||
use Espo\Core\Record\ActionHistory\Action;
|
||||
use Espo\Core\Record\ServiceContainer;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Utils\ObjectUtil;
|
||||
use Espo\Entities\ActionHistoryRecord;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Entities\EmailAddress;
|
||||
use Espo\Entities\PhoneNumber;
|
||||
@@ -137,7 +137,7 @@ class Merger
|
||||
foreach ($sourceEntityList as $sourceEntity) {
|
||||
$this->entityManager->removeEntity($sourceEntity);
|
||||
|
||||
$service->processActionHistoryRecord(ActionHistoryRecord::ACTION_DELETE, $sourceEntity);
|
||||
$service->processActionHistoryRecord(Action::DELETE, $sourceEntity);
|
||||
}
|
||||
|
||||
if ($hasPhoneNumber) {
|
||||
@@ -152,7 +152,7 @@ class Merger
|
||||
|
||||
$this->entityManager->saveEntity($entity);
|
||||
|
||||
$service->processActionHistoryRecord(ActionHistoryRecord::ACTION_UPDATE, $entity);
|
||||
$service->processActionHistoryRecord(Action::UPDATE, $entity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
namespace Espo\Core\MassAction\Actions;
|
||||
|
||||
use Espo\Core\Record\ActionHistory\Action;
|
||||
use Espo\Entities\ActionHistoryRecord;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Core\Acl;
|
||||
@@ -97,7 +98,7 @@ class MassDelete implements MassAction
|
||||
|
||||
$count++;
|
||||
|
||||
$service->processActionHistoryRecord(ActionHistoryRecord::ACTION_DELETE, $entity);
|
||||
$service->processActionHistoryRecord(Action::DELETE, $entity);
|
||||
}
|
||||
|
||||
$result = [
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Record\ActionHistory;
|
||||
|
||||
class Action
|
||||
{
|
||||
public const CREATE = 'create';
|
||||
public const READ = 'read';
|
||||
public const UPDATE = 'update';
|
||||
public const DELETE = 'delete';
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Record\ActionHistory;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
/**
|
||||
* Logs actions users do with records.
|
||||
*/
|
||||
interface ActionLogger
|
||||
{
|
||||
/**
|
||||
* Log an action.
|
||||
*
|
||||
* @param Action::* $action
|
||||
*/
|
||||
public function log(string $action, Entity $entity): void;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Record\ActionHistory;
|
||||
|
||||
use Espo\Core\Field\LinkParent;
|
||||
use Espo\Entities\ActionHistoryRecord;
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
class DefaultActionLogger implements ActionLogger
|
||||
{
|
||||
public function __construct(
|
||||
private EntityManager $entityManager,
|
||||
private User $user
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function log(string $action, Entity $entity): void
|
||||
{
|
||||
$historyRecord = $this->entityManager
|
||||
->getRepositoryByClass(ActionHistoryRecord::class)
|
||||
->getNew();
|
||||
|
||||
$historyRecord
|
||||
->setAction($action)
|
||||
->setUserId($this->user->getId())
|
||||
->setAuthTokenId($this->user->get('authTokenId'))
|
||||
->setAuthLogRecordId($this->user->get('authLogRecordId'))
|
||||
->setIpAddress($this->user->get('ipAddress'))
|
||||
->setTarget(LinkParent::createFromEntity($entity));
|
||||
|
||||
$this->entityManager->saveEntity($historyRecord);
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,10 @@ use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\ForbiddenSilent;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Core\Exceptions\NotFoundSilent;
|
||||
use Espo\Core\Field\LinkParent;
|
||||
use Espo\Core\ORM\Entity as CoreEntity;
|
||||
use Espo\Core\Record\Access\LinkCheck;
|
||||
use Espo\Core\Record\ActionHistory\Action;
|
||||
use Espo\Core\Record\ActionHistory\ActionLogger;
|
||||
use Espo\Core\Record\Formula\Processor as FormulaProcessor;
|
||||
use Espo\Core\Utils\Json;
|
||||
use Espo\Core\Acl;
|
||||
@@ -66,8 +67,7 @@ use Espo\ORM\EntityManager;
|
||||
use Espo\ORM\Query\Part\WhereClause;
|
||||
use Espo\Tools\Stream\Service as StreamService;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Entities\ActionHistoryRecord;
|
||||
use Hoa\Ustring\Search;
|
||||
|
||||
use stdClass;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
@@ -189,6 +189,7 @@ class Service implements Crud,
|
||||
private ?ListLoadProcessor $listLoadProcessor = null;
|
||||
private ?DuplicateFinder $duplicateFinder = null;
|
||||
private ?LinkCheck $linkCheck = null;
|
||||
private ?ActionLogger $actionLogger = null;
|
||||
|
||||
protected const MAX_SELECT_TEXT_ATTRIBUTE_LENGTH = 10000;
|
||||
|
||||
@@ -208,7 +209,7 @@ class Service implements Crud,
|
||||
/**
|
||||
* Add an action-history record.
|
||||
*
|
||||
* @param ActionHistoryRecord::ACTION_* $action
|
||||
* @param Action::* $action
|
||||
*/
|
||||
public function processActionHistoryRecord(string $action, Entity $entity): void
|
||||
{
|
||||
@@ -220,18 +221,16 @@ class Service implements Crud,
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var ActionHistoryRecord $historyRecord */
|
||||
$historyRecord = $this->entityManager->getNewEntity(ActionHistoryRecord::ENTITY_TYPE);
|
||||
$this->getActionLogger()->log($action, $entity);
|
||||
}
|
||||
|
||||
$historyRecord
|
||||
->setAction($action)
|
||||
->setUserId($this->user->getId())
|
||||
->setAuthTokenId($this->user->get('authTokenId'))
|
||||
->setAuthLogRecordId($this->user->get('authLogRecordId'))
|
||||
->setIpAddress($this->user->get('ipAddress'))
|
||||
->setTarget(LinkParent::createFromEntity($entity));
|
||||
private function getActionLogger(): ActionLogger
|
||||
{
|
||||
if (!$this->actionLogger) {
|
||||
$this->actionLogger = $this->injectableFactory->createResolved(ActionLogger::class);
|
||||
}
|
||||
|
||||
$this->entityManager->saveEntity($historyRecord);
|
||||
return $this->actionLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,7 +258,7 @@ class Service implements Crud,
|
||||
}
|
||||
|
||||
$this->recordHookManager->processBeforeRead($entity, $params);
|
||||
$this->processActionHistoryRecord(ActionHistoryRecord::ACTION_READ, $entity);
|
||||
$this->processActionHistoryRecord(Action::READ, $entity);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
@@ -709,7 +708,7 @@ class Service implements Crud,
|
||||
$this->afterCreateProcessDuplicating($entity, $params);
|
||||
$this->loadAdditionalFields($entity);
|
||||
$this->prepareEntityForOutput($entity);
|
||||
$this->processActionHistoryRecord(ActionHistoryRecord::ACTION_CREATE, $entity);
|
||||
$this->processActionHistoryRecord(Action::CREATE, $entity);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
@@ -777,7 +776,7 @@ class Service implements Crud,
|
||||
|
||||
$this->afterUpdateEntity($entity, $data);
|
||||
$this->prepareEntityForOutput($entity);
|
||||
$this->processActionHistoryRecord(ActionHistoryRecord::ACTION_UPDATE, $entity);
|
||||
$this->processActionHistoryRecord(Action::UPDATE, $entity);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
@@ -813,7 +812,7 @@ class Service implements Crud,
|
||||
$this->beforeDeleteEntity($entity);
|
||||
$this->getRepository()->remove($entity);
|
||||
$this->afterDeleteEntity($entity);
|
||||
$this->processActionHistoryRecord(ActionHistoryRecord::ACTION_DELETE, $entity);
|
||||
$this->processActionHistoryRecord(Action::DELETE, $entity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,18 +31,19 @@ namespace Espo\Entities;
|
||||
|
||||
use Espo\Core\Field\LinkParent;
|
||||
use Espo\Core\ORM\Entity;
|
||||
use Espo\Core\Record\ActionHistory\Action;
|
||||
|
||||
class ActionHistoryRecord extends Entity
|
||||
{
|
||||
public const ENTITY_TYPE = 'ActionHistoryRecord';
|
||||
|
||||
public const ACTION_READ = 'read';
|
||||
public const ACTION_UPDATE = 'update';
|
||||
public const ACTION_CREATE = 'create';
|
||||
public const ACTION_DELETE = 'delete';
|
||||
public const ACTION_CREATE = Action::CREATE;
|
||||
public const ACTION_READ = Action::READ;
|
||||
public const ACTION_UPDATE = Action::UPDATE;
|
||||
public const ACTION_DELETE = Action::DELETE;
|
||||
|
||||
/**
|
||||
* @param self::ACTION_* $action
|
||||
* @param Action::* $action
|
||||
*/
|
||||
public function setAction(string $action): self
|
||||
{
|
||||
|
||||
@@ -29,33 +29,23 @@
|
||||
|
||||
namespace Espo\Tools\ActionHistory;
|
||||
|
||||
use Espo\Core\Record\ActionHistory\Action;
|
||||
use Espo\Core\Record\Collection as RecordCollection;
|
||||
use Espo\Entities\ActionHistoryRecord;
|
||||
use Espo\Core\FieldProcessing\ListLoadProcessor;
|
||||
use Espo\Core\ORM\EntityManager;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Utils\Util;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
class Service
|
||||
{
|
||||
private Metadata $metadata;
|
||||
private EntityManager $entityManager;
|
||||
private User $user;
|
||||
private ListLoadProcessor $listLoadProcessor;
|
||||
|
||||
public function __construct(
|
||||
Metadata $metadata,
|
||||
EntityManager $entityManager,
|
||||
User $user,
|
||||
ListLoadProcessor $listLoadProcessor
|
||||
) {
|
||||
$this->metadata = $metadata;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->user = $user;
|
||||
$this->listLoadProcessor = $listLoadProcessor;
|
||||
}
|
||||
private Metadata $metadata,
|
||||
private EntityManager $entityManager,
|
||||
private User $user,
|
||||
private ListLoadProcessor $listLoadProcessor
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return RecordCollection<ActionHistoryRecord>
|
||||
@@ -78,7 +68,7 @@ class Service
|
||||
->getRDBRepositoryByClass(ActionHistoryRecord::class)
|
||||
->where([
|
||||
'userId' => $this->user->getId(),
|
||||
'action' => ActionHistoryRecord::ACTION_READ,
|
||||
'action' => Action::READ,
|
||||
'targetType' => $targetTypeList,
|
||||
])
|
||||
->order('MAX:createdAt', 'DESC')
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
|
||||
namespace Espo\Tools\Import;
|
||||
|
||||
use Espo\Entities\ActionHistoryRecord;
|
||||
use GuzzleHttp\Psr7\Utils as Psr7Utils;
|
||||
|
||||
use Espo\Core\Record\ActionHistory\Action;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\Query\DeleteBuilder;
|
||||
use Espo\ORM\Type\RelationType;
|
||||
use GuzzleHttp\Psr7\Utils as Psr7Utils;
|
||||
|
||||
use Espo\Core\ORM\Repository\Option\SaveOption;
|
||||
use Espo\Entities\ImportEntity as ImportEntityEntity;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
@@ -98,12 +98,12 @@ class Service
|
||||
$id = $result->getId();
|
||||
|
||||
if ($id) {
|
||||
$import = $this->entityManager->getEntity(ImportEntity::ENTITY_TYPE, $id);
|
||||
$import = $this->entityManager->getEntityById(ImportEntity::ENTITY_TYPE, $id);
|
||||
|
||||
if ($import) {
|
||||
$this->recordServiceContainer
|
||||
->get(ImportEntity::ENTITY_TYPE)
|
||||
->processActionHistoryRecord(ActionHistoryRecord::ACTION_CREATE, $import);
|
||||
->processActionHistoryRecord(Action::CREATE, $import);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ class Service
|
||||
|
||||
$this->recordServiceContainer
|
||||
->get(ImportEntity::ENTITY_TYPE)
|
||||
->processActionHistoryRecord(ActionHistoryRecord::ACTION_DELETE, $import);
|
||||
->processActionHistoryRecord(Action::DELETE, $import);
|
||||
}
|
||||
|
||||
private function deleteRelations(Entity $entity): void
|
||||
|
||||
@@ -40,6 +40,7 @@ use Espo\Core\MassAction\Result;
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\Record\Access\LinkCheck;
|
||||
use Espo\Core\Record\ActionHistory\Action as RecordAction;
|
||||
use Espo\Core\Record\ServiceFactory;
|
||||
use Espo\Core\Record\Service;
|
||||
|
||||
@@ -198,7 +199,7 @@ class Processor
|
||||
'modifiedById' => $this->user->getId(),
|
||||
]);
|
||||
|
||||
$service->processActionHistoryRecord(ActionHistoryRecord::ACTION_UPDATE, $entity);
|
||||
$service->processActionHistoryRecord(RecordAction::UPDATE, $entity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user