diff --git a/application/Espo/Classes/Acl/Attachment/AccessChecker.php b/application/Espo/Classes/Acl/Attachment/AccessChecker.php index c74cad6ff3..3e485d4b09 100644 --- a/application/Espo/Classes/Acl/Attachment/AccessChecker.php +++ b/application/Espo/Classes/Acl/Attachment/AccessChecker.php @@ -93,6 +93,7 @@ class AccessChecker implements AccessEntityCREDChecker } if ($parent->getEntityType() === 'Note') { + /** @var Note $parent */ $result = $this->checkEntityReadNoteParent($user, $parent); if ($result !== null) { diff --git a/application/Espo/Classes/Acl/User/AccessChecker.php b/application/Espo/Classes/Acl/User/AccessChecker.php index e56338b37a..bc5f21a1ce 100644 --- a/application/Espo/Classes/Acl/User/AccessChecker.php +++ b/application/Espo/Classes/Acl/User/AccessChecker.php @@ -42,6 +42,9 @@ use Espo\Core\{ AclManager, }; +/** + * @implements AccessEntityCREDSChecker + */ class AccessChecker implements AccessEntityCREDSChecker { use DefaultAccessCheckerDependency; @@ -132,6 +135,8 @@ class AccessChecker implements AccessEntityCREDSChecker public function checkEntityStream(User $user, Entity $entity, ScopeData $data): bool { + /** @var User $entity */ + return $this->aclManager->checkUserPermission($user, $entity, 'user'); } } diff --git a/application/Espo/Classes/AclPortal/Attachment/AccessChecker.php b/application/Espo/Classes/AclPortal/Attachment/AccessChecker.php index 416903c7fd..ffb5e45446 100644 --- a/application/Espo/Classes/AclPortal/Attachment/AccessChecker.php +++ b/application/Espo/Classes/AclPortal/Attachment/AccessChecker.php @@ -45,6 +45,9 @@ use Espo\Core\{ Portal\Acl\Traits\DefaultAccessCheckerDependency, }; +/** + * @implements AccessEntityCREDChecker + */ class AccessChecker implements AccessEntityCREDChecker { use DefaultAccessCheckerDependency; @@ -94,6 +97,7 @@ class AccessChecker implements AccessEntityCREDChecker } if ($parent->getEntityType() === 'Note') { + /** @var Note $parent */ $result = $this->checkEntityReadNoteParent($user, $parent); if ($result !== null) { diff --git a/application/Espo/Classes/DuplicateWhereBuilders/Company.php b/application/Espo/Classes/DuplicateWhereBuilders/Company.php index 65075e7c38..5ef8483bcb 100644 --- a/application/Espo/Classes/DuplicateWhereBuilders/Company.php +++ b/application/Espo/Classes/DuplicateWhereBuilders/Company.php @@ -44,6 +44,8 @@ class Company implements WhereBuilder { public function build(Entity $entity): ?WhereItem { + assert($entity instanceof CoreEntity); + $orBuilder = OrGroup::createBuilder(); $toCheck = false; diff --git a/application/Espo/Classes/DuplicateWhereBuilders/Person.php b/application/Espo/Classes/DuplicateWhereBuilders/Person.php index c2d4818b7e..553281a455 100644 --- a/application/Espo/Classes/DuplicateWhereBuilders/Person.php +++ b/application/Espo/Classes/DuplicateWhereBuilders/Person.php @@ -47,6 +47,8 @@ class Person implements WhereBuilder { public function build(Entity $entity): ?WhereItem { + assert($entity instanceof CoreEntity); + $orBuilder = OrGroup::createBuilder(); $toCheck = false; diff --git a/application/Espo/Classes/FieldProcessing/Email/AddressDataLoader.php b/application/Espo/Classes/FieldProcessing/Email/AddressDataLoader.php index cfaec19838..46ab79e31b 100644 --- a/application/Espo/Classes/FieldProcessing/Email/AddressDataLoader.php +++ b/application/Espo/Classes/FieldProcessing/Email/AddressDataLoader.php @@ -39,6 +39,9 @@ use Espo\Core\{ use Espo\Repositories\Email as EmailRepository; +/** + * @implements Loader<\Espo\Entities\Email> + */ class AddressDataLoader implements Loader { private $entityManager; diff --git a/application/Espo/Classes/FieldProcessing/Import/CountsLoader.php b/application/Espo/Classes/FieldProcessing/Import/CountsLoader.php index f4084d7baa..8852151839 100644 --- a/application/Espo/Classes/FieldProcessing/Import/CountsLoader.php +++ b/application/Espo/Classes/FieldProcessing/Import/CountsLoader.php @@ -39,6 +39,9 @@ use Espo\Core\{ use Espo\Repositories\Import as ImportRepository; +/** + * @implements Loader<\Espo\Entities\Import> + */ class CountsLoader implements Loader { private $entityManager; diff --git a/application/Espo/Classes/RecordHooks/Team/BeforeLinkUserCheck.php b/application/Espo/Classes/RecordHooks/Team/BeforeLinkUserCheck.php index eda6109fe5..0c3185fdc4 100644 --- a/application/Espo/Classes/RecordHooks/Team/BeforeLinkUserCheck.php +++ b/application/Espo/Classes/RecordHooks/Team/BeforeLinkUserCheck.php @@ -36,6 +36,9 @@ use Espo\ORM\Entity; use Espo\Entities\User; +/** + * @implements LinkHook<\Espo\Entities\Team> + */ class BeforeLinkUserCheck implements LinkHook { public function process(Entity $entity, string $link, Entity $foreignEntity): void @@ -44,6 +47,8 @@ class BeforeLinkUserCheck implements LinkHook return; } + assert($foreignEntity instanceof User); + $this->processUserCheck($foreignEntity); } diff --git a/application/Espo/Core/Acl/AccessEntityCREDChecker.php b/application/Espo/Core/Acl/AccessEntityCREDChecker.php index b1e71d1f40..c12a307fe3 100644 --- a/application/Espo/Core/Acl/AccessEntityCREDChecker.php +++ b/application/Espo/Core/Acl/AccessEntityCREDChecker.php @@ -29,6 +29,11 @@ namespace Espo\Core\Acl; +/** + * @template TEntity of \Espo\ORM\Entity + * @extends AccessEntityCreateChecker, AccessEntityCreateChecker, AccessEntityReadChecker, + * AccessEntityEditChecker, AccessEntityDeleteChecker + */ interface AccessEntityCREDChecker extends AccessEntityCreateChecker, diff --git a/application/Espo/Core/Acl/AccessEntityCREDSChecker.php b/application/Espo/Core/Acl/AccessEntityCREDSChecker.php index 80f64b3efe..7e61b48556 100644 --- a/application/Espo/Core/Acl/AccessEntityCREDSChecker.php +++ b/application/Espo/Core/Acl/AccessEntityCREDSChecker.php @@ -29,6 +29,11 @@ namespace Espo\Core\Acl; +/** + * @template TEntity of \Espo\ORM\Entity + * @extends AccessEntityCreateChecker, AccessEntityCreateChecker, AccessEntityReadChecker, + * AccessEntityEditChecker, AccessEntityDeleteChecker, AccessEntityStreamChecker + */ interface AccessEntityCREDSChecker extends AccessEntityCreateChecker, diff --git a/application/Espo/Core/Acl/AccessEntityCreateChecker.php b/application/Espo/Core/Acl/AccessEntityCreateChecker.php index 86c2dc99e8..9dea19114b 100644 --- a/application/Espo/Core/Acl/AccessEntityCreateChecker.php +++ b/application/Espo/Core/Acl/AccessEntityCreateChecker.php @@ -30,13 +30,17 @@ namespace Espo\Core\Acl; use Espo\ORM\Entity; - use Espo\Entities\User; +/** + * @template TEntity of Entity + */ interface AccessEntityCreateChecker extends AccessCreateChecker { /** * Check 'create' access for an entity. + * + * @phpstan-param TEntity $entity */ public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool; } diff --git a/application/Espo/Core/Acl/AccessEntityDeleteChecker.php b/application/Espo/Core/Acl/AccessEntityDeleteChecker.php index c3fb213e33..6e47b174b7 100644 --- a/application/Espo/Core/Acl/AccessEntityDeleteChecker.php +++ b/application/Espo/Core/Acl/AccessEntityDeleteChecker.php @@ -30,13 +30,17 @@ namespace Espo\Core\Acl; use Espo\ORM\Entity; - use Espo\Entities\User; +/** + * @template TEntity of Entity + */ interface AccessEntityDeleteChecker extends AccessDeleteChecker { /** * Check 'delete' access for an entity. + * + * @phpstan-param TEntity $entity */ public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool; } diff --git a/application/Espo/Core/Acl/AccessEntityEditChecker.php b/application/Espo/Core/Acl/AccessEntityEditChecker.php index 12d0256d11..d35b90a6a0 100644 --- a/application/Espo/Core/Acl/AccessEntityEditChecker.php +++ b/application/Espo/Core/Acl/AccessEntityEditChecker.php @@ -30,13 +30,17 @@ namespace Espo\Core\Acl; use Espo\ORM\Entity; - use Espo\Entities\User; +/** + * @template TEntity of Entity + */ interface AccessEntityEditChecker extends AccessEditChecker { /** * Check 'edit' access for an entity. + * + * @phpstan-param TEntity $entity */ public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool; } diff --git a/application/Espo/Core/Acl/AccessEntityReadChecker.php b/application/Espo/Core/Acl/AccessEntityReadChecker.php index d1d408ed4a..c659c01e75 100644 --- a/application/Espo/Core/Acl/AccessEntityReadChecker.php +++ b/application/Espo/Core/Acl/AccessEntityReadChecker.php @@ -30,13 +30,17 @@ namespace Espo\Core\Acl; use Espo\ORM\Entity; - use Espo\Entities\User; +/** + * @template TEntity of Entity + */ interface AccessEntityReadChecker extends AccessReadChecker { /** * Check 'read' access for entity. + * + * @phpstan-param TEntity $entity */ public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool; } diff --git a/application/Espo/Core/Acl/AccessEntityStreamChecker.php b/application/Espo/Core/Acl/AccessEntityStreamChecker.php index d4fa8c252a..de90890079 100644 --- a/application/Espo/Core/Acl/AccessEntityStreamChecker.php +++ b/application/Espo/Core/Acl/AccessEntityStreamChecker.php @@ -30,13 +30,17 @@ namespace Espo\Core\Acl; use Espo\ORM\Entity; - use Espo\Entities\User; +/** + * @template TEntity of Entity + */ interface AccessEntityStreamChecker extends AccessStreamChecker { /** * Check 'stream' access for an entity. + * + * @phpstan-param TEntity $entity */ public function checkEntityStream(User $user, Entity $entity, ScopeData $data): bool; } diff --git a/application/Espo/Core/Duplicate/WhereBuilder.php b/application/Espo/Core/Duplicate/WhereBuilder.php index 4ee93ecfbc..8ccff3dcf6 100644 --- a/application/Espo/Core/Duplicate/WhereBuilder.php +++ b/application/Espo/Core/Duplicate/WhereBuilder.php @@ -34,7 +34,13 @@ use Espo\ORM\{ Entity, }; +/** + * @template TEntity of Entity + */ interface WhereBuilder { + /** + * @phpstan-param TEntity $entity + */ public function build(Entity $entity): ?WhereItem; } diff --git a/application/Espo/Core/FieldProcessing/Loader.php b/application/Espo/Core/FieldProcessing/Loader.php index 6d4a8d36b7..4183be3b04 100644 --- a/application/Espo/Core/FieldProcessing/Loader.php +++ b/application/Espo/Core/FieldProcessing/Loader.php @@ -35,8 +35,13 @@ use Espo\Core\FieldProcessing\Loader\Params; /** * Processes loading special fields before output. + * + * @template TEntity of Entity */ interface Loader { + /** + * @phpstan-param TEntity $entity + */ public function process(Entity $entity, Params $params): void; } diff --git a/application/Espo/Core/Record/Hook/LinkHook.php b/application/Espo/Core/Record/Hook/LinkHook.php index c0961348cd..6c5a26948c 100644 --- a/application/Espo/Core/Record/Hook/LinkHook.php +++ b/application/Espo/Core/Record/Hook/LinkHook.php @@ -31,7 +31,13 @@ namespace Espo\Core\Record\Hook; use Espo\ORM\Entity; +/** + * @template TEntity of Entity + */ interface LinkHook { + /** + * @phpstan-param TEntity $entity + */ public function process(Entity $entity, string $link, Entity $foreignEntity): void; } diff --git a/application/Espo/EntryPoints/Pdf.php b/application/Espo/EntryPoints/Pdf.php index 24112bf1b1..86b865b2c2 100644 --- a/application/Espo/EntryPoints/Pdf.php +++ b/application/Espo/EntryPoints/Pdf.php @@ -87,7 +87,7 @@ class Pdf implements EntryPoint ->setHeader('Content-Disposition', 'inline; filename="' . basename($fileName) . '"'); if (!$request->getServerParam('HTTP_ACCEPT_ENCODING')) { - $response->setHeader('Content-Length', strlen($contents)); + $response->setHeader('Content-Length', (string) strlen($contents)); } $response->writeBody($contents); diff --git a/application/Espo/Hooks/Common/FieldProcessing.php b/application/Espo/Hooks/Common/FieldProcessing.php index 2f078284a5..02a10c4e37 100644 --- a/application/Espo/Hooks/Common/FieldProcessing.php +++ b/application/Espo/Hooks/Common/FieldProcessing.php @@ -30,8 +30,8 @@ namespace Espo\Hooks\Common; use Espo\ORM\Entity; - use Espo\Core\FieldProcessing\SaveProcessor; +use Espo\Core\ORM\Entity as CoreEntity; class FieldProcessing { @@ -50,6 +50,10 @@ class FieldProcessing return; } + if (!$entity instanceof CoreEntity) { + return; + } + $this->saveProcessor->process($entity, $options); } } diff --git a/application/Espo/Hooks/Common/Webhook.php b/application/Espo/Hooks/Common/Webhook.php index b4d941c23f..34ddbe1812 100644 --- a/application/Espo/Hooks/Common/Webhook.php +++ b/application/Espo/Hooks/Common/Webhook.php @@ -30,6 +30,7 @@ namespace Espo\Hooks\Common; use Espo\ORM\Entity; +use Espo\Core\ORM\Entity as CoreEntity; use Espo\Core\{ Utils\Metadata, @@ -60,6 +61,10 @@ class Webhook return; } + if (!$entity instanceof CoreEntity) { + return; + } + if ($entity->isNew()) { $this->webhookManager->processCreate($entity); } @@ -78,6 +83,10 @@ class Webhook return; } + if (!$entity instanceof CoreEntity) { + return; + } + $this->webhookManager->processDelete($entity); } } diff --git a/application/Espo/Hooks/Note/Mentions.php b/application/Espo/Hooks/Note/Mentions.php index d1c63e70e7..5771a5d31f 100644 --- a/application/Espo/Hooks/Note/Mentions.php +++ b/application/Espo/Hooks/Note/Mentions.php @@ -31,6 +31,7 @@ namespace Espo\Hooks\Note; use Espo\Tools\Notification\NoteMentionHookProcessor; use Espo\ORM\Entity; +use Espo\Entities\Note; class Mentions { @@ -49,6 +50,8 @@ class Mentions return; } + assert($entity instanceof Note); + $this->processor->beforeSave($entity); } } diff --git a/application/Espo/Hooks/Note/Notifications.php b/application/Espo/Hooks/Note/Notifications.php index 39e5acae6b..43d2781048 100644 --- a/application/Espo/Hooks/Note/Notifications.php +++ b/application/Espo/Hooks/Note/Notifications.php @@ -31,6 +31,7 @@ namespace Espo\Hooks\Note; use Espo\ORM\Entity; use Espo\Tools\Notification\NoteHookProcessor; +use Espo\Entities\Note; class Notifications { @@ -49,6 +50,8 @@ class Notifications return; } + assert($entity instanceof Note); + $this->processor->afterSave($entity); } } diff --git a/application/Espo/Hooks/Sms/Numbers.php b/application/Espo/Hooks/Sms/Numbers.php index d77107aba8..4477c85731 100644 --- a/application/Espo/Hooks/Sms/Numbers.php +++ b/application/Espo/Hooks/Sms/Numbers.php @@ -47,6 +47,8 @@ class Numbers public function beforeSave(Entity $entity): void { + assert($entity instanceof Sms); + $this->processNumbers($entity); } diff --git a/application/Espo/Repositories/Attachment.php b/application/Espo/Repositories/Attachment.php index 07a482732e..afa9e50d63 100644 --- a/application/Espo/Repositories/Attachment.php +++ b/application/Espo/Repositories/Attachment.php @@ -76,7 +76,7 @@ class Attachment extends Database implements } } - protected function processBeforeSaveNew(Entity $entity): void + protected function processBeforeSaveNew(AttachmentEntity $entity): void { if (!$entity->get('storage')) { $defaultStorage = $this->config->get('defaultFileStorage');