record hook

This commit is contained in:
Yuri Kuznetsov
2021-06-09 15:34:36 +03:00
parent 8fa1e3dd79
commit c0a815f36e
26 changed files with 918 additions and 28 deletions
@@ -0,0 +1,60 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Classes\RecordHooks\Team;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Record\Hook\LinkHook;
use Espo\ORM\Entity;
use Espo\Entities\User;
class BeforeLinkUserCheck implements LinkHook
{
public function process(Entity $entity, string $link, Entity $foreignEntity): void
{
if ($link !== 'users') {
return;
}
$this->processUserCheck($foreignEntity);
}
private function processUserCheck(User $user): void
{
if ($user->isPortal()) {
throw new Forbidden("Can't add portal users to team.");
}
if ($user->isSystem()) {
throw new Forbidden("Can't add system users to team.");
}
}
}
@@ -31,11 +31,11 @@ namespace Espo\Controllers;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\{
Controllers\RecordBase,
Api\Request,
Api\Response,
Record\ReadParams,
};
use StdClass;
@@ -108,7 +108,9 @@ class ExternalAccount extends RecordBase
{
$id = $request->getRouteParam('id');
return $this->getRecordService()->read($id)->getValueMap();
return $this->getRecordService()
->read($id, ReadParams::create())
->getValueMap();
}
public function putActionUpdate(Request $request, Response $response): StdClass
@@ -117,7 +119,7 @@ class ExternalAccount extends RecordBase
$data = $request->getParsedBody();
list($integration, $userId) = explode('__', $id);
list ($integration, $userId) = explode('__', $id);
if ($this->user->getId() !== $userId && !$this->user->isAdmin()) {
throw new Forbidden();
@@ -143,7 +145,7 @@ class ExternalAccount extends RecordBase
$id = $data->id;
$code = $data->code;
list($integration, $userId) = explode('__', $id);
list ($integration, $userId) = explode('__', $id);
if ($this->user->getId() != $userId && !$this->user->isAdmin()) {
throw new Forbidden();
@@ -108,6 +108,11 @@ class DefaultBinding implements BindingProcessor
'recordServiceContainer'
);
$binder->bindService(
'Espo\\Core\\Record\\HookManager',
'recordHookManager'
);
$binder->bindService(
'Espo\\Core\\Utils\\HookManager',
'hookManager'
@@ -39,7 +39,9 @@ use Espo\Core\{
Record\ServiceContainer as RecordServiceContainer,
Record\SearchParamsFetcher,
Record\CreateParamsFetcher,
Record\ReadParamsFetcher,
Record\UpdateParamsFetcher,
Record\DeleteParamsFetcher,
Container,
Acl,
AclManager,
@@ -76,11 +78,21 @@ class RecordBase extends Base implements Di\EntityManagerAware
*/
protected $createParamsFetcher;
/**
* @var ReadParamsFetcher
*/
protected $readParamsFetcher;
/**
* @var UpdateParamsFetcher
*/
protected $updateParamsFetcher;
/**
* @var DeleteParamsFetcher
*/
protected $deleteParamsFetcher;
/**
* @var RecordServiceContainer
*/
@@ -100,7 +112,9 @@ class RecordBase extends Base implements Di\EntityManagerAware
public function __construct(
SearchParamsFetcher $searchParamsFetcher,
CreateParamsFetcher $createParamsFetcher,
ReadParamsFetcher $readParamsFetcher,
UpdateParamsFetcher $updateParamsFetcher,
DeleteParamsFetcher $deleteParamsFetcher,
RecordServiceContainer $recordServiceContainer,
Config $config,
User $user,
@@ -113,7 +127,9 @@ class RecordBase extends Base implements Di\EntityManagerAware
) {
$this->searchParamsFetcher = $searchParamsFetcher;
$this->createParamsFetcher = $createParamsFetcher;
$this->readParamsFetcher = $readParamsFetcher;
$this->updateParamsFetcher = $updateParamsFetcher;
$this->deleteParamsFetcher = $deleteParamsFetcher;
$this->recordServiceContainer = $recordServiceContainer;
$this->config = $config;
$this->user = $user;
@@ -153,7 +169,9 @@ class RecordBase extends Base implements Di\EntityManagerAware
$id = $request->getRouteParam('id');
$entity = $this->getRecordService()->read($id);
$params = $this->readParamsFetcher->fetch($request);
$entity = $this->getRecordService()->read($id, $params);
if (!$entity) {
throw new NotFound();
@@ -239,7 +257,9 @@ class RecordBase extends Base implements Di\EntityManagerAware
$id = $request->getRouteParam('id');
$this->getRecordService()->delete($id);
$params = $this->deleteParamsFetcher->fetch($request);
$this->getRecordService()->delete($id, $params);
return true;
}
@@ -0,0 +1,37 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Di;
use Espo\Core\Record\HookManager as RecordHookManager;
interface RecordHookManagerAware
{
public function setRecordHookManager(RecordHookManager $recordHookManager): void;
}
@@ -0,0 +1,45 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Di;
use Espo\Core\Record\HookManager as RecordHookManager;
trait RecordHookManagerSetter
{
/**
* @var RecordHookManager
*/
protected $recordHookManager;
public function setRecordHookManager(RecordHookManager $recordHookManager): void
{
$this->recordHookManager = $recordHookManager;
}
}
+5 -5
View File
@@ -31,27 +31,27 @@ namespace Espo\Core\Record;
use Espo\ORM\Entity;
use StdClass;
use stdClass;
interface Crud
{
/**
* Create a record.
*/
public function create(StdClass $data, CreateParams $params): Entity;
public function create(stdClass $data, CreateParams $params): Entity;
/**
* Read a record.
*/
public function read(string $id): Entity;
public function read(string $id, ReadParams $params): Entity;
/**
* Update a record.
*/
public function update(string $id, StdClass $data, UpdateParams $params): Entity;
public function update(string $id, stdClass $data, UpdateParams $params): Entity;
/**
* Delete a record.
*/
public function delete(string $id): void;
public function delete(string $id, DeleteParams $params): void;
}
@@ -0,0 +1,40 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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;
class DeleteParams
{
public function __construct() {}
public static function create(): self
{
return new self();
}
}
@@ -0,0 +1,42 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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;
use Espo\Core\Api\Request;
class DeleteParamsFetcher
{
public function __construct() {}
public function fetch(Request $request): DeleteParams
{
return DeleteParams::create();
}
}
@@ -0,0 +1,39 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\ORM\Entity;
use Espo\Core\Record\CreateParams;
interface CreateHook
{
public function process(Entity $entity, CreateParams $params): void;
}
@@ -0,0 +1,39 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\ORM\Entity;
use Espo\Core\Record\DeleteParams;
interface DeleteHook
{
public function process(Entity $entity, DeleteParams $params): void;
}
@@ -0,0 +1,37 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\ORM\Entity;
interface LinkHook
{
public function process(Entity $entity, string $link, Entity $foreignEntity): void;
}
@@ -0,0 +1,104 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\Core\Utils\Metadata;
use Espo\Core\InjectableFactory;
use ReflectionClass;
use RuntimeException;
class Provider
{
private $metadata;
private $injectableFactory;
private $map = [];
private $typeInterfaceMap = [
Type::BEFORE_CREATE => CreateHook::class,
Type::BEFORE_READ => ReadHook::class,
Type::BEFORE_UPDATE => UpdateHook::class,
Type::BEFORE_DELETE => DeleteHook::class,
Type::BEFORE_LINK => LinkHook::class,
Type::BEFORE_UNLINK => UnlinkHook::class,
];
public function __construct(Metadata $metadata, InjectableFactory $injectableFactory)
{
$this->metadata = $metadata;
$this->injectableFactory = $injectableFactory;
}
/**
* @return object[]
*/
public function getList(string $entityType, string $type): array
{
$key = $entityType . '_' . $type;
if (!array_key_exists($key, $this->map)) {
$this->map[$key] = $this->loadList($entityType, $type);
}
return $this->map[$key];
}
/**
* @return object[]
*/
private function loadList(string $entityType, string $type): array
{
$key = $type . 'HookClassNameList';
$classNameList = $this->metadata->get(['recordDefs', $entityType, $key]) ?? [];
$interfaceName = $this->typeInterfaceMap[$type] ?? null;
if (!$interfaceName) {
throw new RuntimeException("Unsupported record hook type '{$type}'.");
}
$list = [];
foreach ($classNameList as $className) {
$class = new ReflectionClass($className);
if (!$class->implementsInterface($interfaceName)) {
throw new RuntimeException("Hook '$className' does not implement '{$interfaceName}'.");
}
$list[] = $this->injectableFactory->create($className);
}
return $list;
}
}
@@ -0,0 +1,39 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\ORM\Entity;
use Espo\Core\Record\ReadParams;
interface ReadHook
{
public function process(Entity $entity, ReadParams $params): void;
}
@@ -0,0 +1,45 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
class Type
{
public const BEFORE_CREATE = 'beforeCreate';
public const BEFORE_READ = 'beforeRead';
public const BEFORE_UPDATE = 'beforeUpdate';
public const BEFORE_DELETE = 'beforeDelete';
public const BEFORE_LINK = 'beforeLink';
public const BEFORE_UNLINK = 'beforeUnlink';
}
@@ -0,0 +1,37 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\ORM\Entity;
interface UnlinkHook
{
public function process(Entity $entity, string $link, Entity $foreignEntity): void;
}
@@ -0,0 +1,39 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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\Hook;
use Espo\ORM\Entity;
use Espo\Core\Record\UpdateParams;
interface UpdateHook
{
public function process(Entity $entity, UpdateParams $params): void;
}
@@ -0,0 +1,148 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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;
use Espo\ORM\Entity;
use Espo\Core\Record\CreateParams;
use Espo\Core\Record\ReadParams;
use Espo\Core\Record\UpdateParams;
use Espo\Core\Record\DeleteParams;
use Espo\Core\Record\Hook\{
Provider,
Type,
ReadHook,
CreateHook,
UpdateHook,
DeleteHook,
LinkHook,
UnlinkHook,
};
class HookManager
{
private $provider;
public function __construct(Provider $provider)
{
$this->provider = $provider;
}
public function processBeforeCreate(Entity $entity, CreateParams $params): void
{
foreach ($this->getBeforeCreateHookList($entity->getEntityType()) as $hook) {
$hook->process($entity, $params);
}
}
public function processBeforeRead(Entity $entity, ReadParams $params): void
{
foreach ($this->getBeforeReadHookList($entity->getEntityType()) as $hook) {
$hook->process($entity, $params);
}
}
public function processBeforeUpdate(Entity $entity, UpdateParams $params): void
{
foreach ($this->getBeforeUpdateHookList($entity->getEntityType()) as $hook) {
$hook->process($entity, $params);
}
}
public function processBeforeDelete(Entity $entity, DeleteParams $params): void
{
foreach ($this->getBeforeDeleteHookList($entity->getEntityType()) as $hook) {
$hook->process($entity, $params);
}
}
public function processBeforeLink(Entity $entity, string $link, Entity $foreignEntity): void
{
foreach ($this->getBeforeLinkHookList($entity->getEntityType()) as $hook) {
$hook->process($entity, $link, $foreignEntity);
}
}
public function processBeforeUnlink(Entity $entity, string $link, Entity $foreignEntity): void
{
foreach ($this->getBeforeUnlinkHookList($entity->getEntityType()) as $hook) {
$hook->process($entity, $link, $foreignEntity);
}
}
/**
* @return ReadHook[]
*/
private function getBeforeReadHookList(string $entityType): array
{
return $this->provider->getList($entityType, Type::BEFORE_READ);
}
/**
* @return CreateHook[]
*/
private function getBeforeCreateHookList(string $entityType): array
{
return $this->provider->getList($entityType, Type::BEFORE_CREATE);
}
/**
* @return UpdateHook[]
*/
private function getBeforeUpdateHookList(string $entityType): array
{
return $this->provider->getList($entityType, Type::BEFORE_UPDATE);
}
/**
* @return DeleteHook[]
*/
private function getBeforeDeleteHookList(string $entityType): array
{
return $this->provider->getList($entityType, Type::BEFORE_DELETE);
}
/**
* @return LinkHook[]
*/
private function getBeforeLinkHookList(string $entityType): array
{
return $this->provider->getList($entityType, Type::BEFORE_LINK);
}
/**
* @return UnlinkHook[]
*/
private function getBeforeUnlinkHookList(string $entityType): array
{
return $this->provider->getList($entityType, Type::BEFORE_UNLINK);
}
}
@@ -0,0 +1,40 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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;
class ReadParams
{
public function __construct() {}
public static function create(): self
{
return new self();
}
}
@@ -0,0 +1,42 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 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;
use Espo\Core\Api\Request;
class ReadParamsFetcher
{
public function __construct() {}
public function fetch(Request $request): ReadParams
{
return ReadParams::create();
}
}
+23 -5
View File
@@ -58,6 +58,7 @@ use Espo\Core\{
Select\SelectBuilderFactory,
Record\Crud,
Record\Collection as RecordCollection,
Record\HookManager as RecordHookManager,
FieldValidation\Params as FieldValidationParams,
FieldProcessing\ReadLoadProcessor,
FieldProcessing\ListLoadProcessor,
@@ -87,7 +88,8 @@ class Service implements Crud,
Di\FieldValidationManagerAware,
Di\RecordServiceContainerAware,
Di\SelectBuilderFactoryAware,
Di\AssignmentCheckerManagerAware
Di\AssignmentCheckerManagerAware,
Di\RecordHookManagerAware
{
use Di\ConfigSetter;
use Di\ServiceFactorySetter;
@@ -101,6 +103,7 @@ class Service implements Crud,
use Di\RecordServiceContainerSetter;
use Di\SelectBuilderFactorySetter;
use Di\AssignmentCheckerManagerSetter;
use Di\RecordHookManagerSetter;
protected $getEntityBeforeUpdate = false;
@@ -187,6 +190,11 @@ class Service implements Crud,
*/
protected $selectBuilderFactory;
/**
* @var RecordHookManager
*/
protected $recordHookManager;
private $listLoadProcessor;
private $duplicateFinder;
@@ -250,7 +258,7 @@ class Service implements Crud,
* @throws Error
* @throws NotFoundSilent If no read access.
*/
public function read(string $id): Entity
public function read(string $id, ReadParams $params): Entity
{
if (!$this->acl->check($this->entityType, AclTable::ACTION_READ)) {
throw new ForbiddenSilent();
@@ -266,6 +274,8 @@ class Service implements Crud,
throw new NotFoundSilent("Record {$id} does not exist.");
}
$this->recordHookManager->processBeforeRead($entity, $params);
$this->processActionHistoryRecord('read', $entity);
return $entity;
@@ -668,12 +678,14 @@ class Service implements Crud,
$this->processAssignmentCheck($entity);
$this->beforeUpdateEntity($entity, $data);
if ($this->checkForDuplicatesInUpdate && !$params->skipDuplicateCheck()) {
$this->processDuplicateCheck($entity, $data);
}
$this->recordHookManager->processBeforeUpdate($entity, $params);
$this->beforeUpdateEntity($entity, $data);
$this->entityManager->saveEntity($entity);
$this->afterUpdateEntity($entity, $data);
@@ -692,7 +704,7 @@ class Service implements Crud,
* @throws BadRequest
* @throws NotFound
*/
public function delete(string $id): void
public function delete(string $id, DeleteParams $params): void
{
if (!$this->acl->check($this->entityType, AclTable::ACTION_DELETE)) {
throw new ForbiddenSilent();
@@ -712,6 +724,8 @@ class Service implements Crud,
throw new ForbiddenSilent("No delete access.");
}
$this->recordHookManager->processBeforeDelete($entity, $params);
$this->beforeDeleteEntity($entity);
$this->getRepository()->remove($entity);
@@ -1014,6 +1028,8 @@ class Service implements Crud,
throw new Forbidden();
}
$this->recordHookManager->processBeforeLink($entity, $link, $foreignEntity);
$this->getRepository()->relate($entity, $link, $foreignEntity);
}
@@ -1082,6 +1098,8 @@ class Service implements Crud,
throw new Forbidden();
}
$this->recordHookManager->processBeforeUnlink($entity, $link, $foreignEntity);
$this->getRepository()->unrelate($entity, $link, $foreignEntity);
}
@@ -41,6 +41,9 @@
"recordServiceContainer": {
"className": "Espo\\Core\\Record\\ServiceContainer"
},
"recordHookManager": {
"className": "Espo\\Core\\Record\\HookManager"
},
"templateFileManager": {
"className": "Espo\\Core\\Utils\\TemplateFileManager"
},
@@ -3,5 +3,8 @@
"delete": {
"allowed": true
}
}
},
"beforeLinkHookClassNameList": [
"Espo\\Classes\\RecordHooks\\Team\\BeforeLinkUserCheck"
]
}
@@ -38,6 +38,8 @@ use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Record\ReadParams;
use Espo\Core\Di;
use Exception;
@@ -137,9 +139,9 @@ class ExternalAccount extends Record implements Di\HookManagerAware
}
}
public function read(string $id): Entity
public function read(string $id, ReadParams $params): Entity
{
list($integration, $userId) = explode('__', $id);
list ($integration, $userId) = explode('__', $id);
if ($this->getUser()->id != $userId && !$this->getUser()->isAdmin()) {
throw new Forbidden();
+3 -2
View File
@@ -40,6 +40,7 @@ use Espo\Core\{
Password\Recovery,
Record\CreateParams,
Record\UpdateParams,
Record\DeleteParams,
};
use Espo\ORM\Entity;
@@ -705,7 +706,7 @@ class User extends Record implements
$sender->send($email);
}
public function delete(string $id): void
public function delete(string $id, DeleteParams $params): void
{
if ($id == 'system') {
throw new Forbidden();
@@ -715,7 +716,7 @@ class User extends Record implements
throw new Forbidden();
}
parent::delete($id);
parent::delete($id, $params);
}
public function afterUpdateEntity(Entity $entity, $data)
@@ -29,9 +29,12 @@
namespace tests\integration\Espo\Record;
use Espo\Core\Record\CreateParams;
use Espo\Core\Record\ReadParams;
use Espo\Core\Record\DeleteParams;
class RestoreDeletedTest extends \tests\integration\Core\BaseTestCase
{
public function testDeleted()
{
$app = $this->createApplication();
@@ -40,11 +43,11 @@ class RestoreDeletedTest extends \tests\integration\Core\BaseTestCase
$account = $service->create((object) [
'name' => 'Test'
]);
], CreateParams::create());
$result = $service->delete($account->id);
$result = $service->delete($account->id, DeleteParams::create());
$account = $service->read($account->id);
$account = $service->read($account->id, ReadParams::create());
$this->assertNotNull($account);
@@ -59,13 +62,13 @@ class RestoreDeletedTest extends \tests\integration\Core\BaseTestCase
$account = $service->create((object) [
'name' => 'Test'
]);
], CreateParams::create());
$service->delete($account->id);
$service->delete($account->id, DeleteParams::create());
$service->restoreDeleted($account->id);
$account = $service->read($account->id);
$account = $service->read($account->id, ReadParams::create());
$this->assertNotNull($account);