diff --git a/application/Espo/Services/Stream.php b/application/Espo/Services/Stream.php index 479514b00d..b9d35b5128 100644 --- a/application/Espo/Services/Stream.php +++ b/application/Espo/Services/Stream.php @@ -71,10 +71,19 @@ use DateTime; class Stream { + /** + * @var ?array + */ private $statusStyles = null; + /** + * @var ?array + */ private $statusFields = null; + /** + * @var string[] + */ private $successDefaultStyleList = [ 'Held', 'Closed Won', @@ -84,12 +93,29 @@ class Stream 'Sold', ]; + /** + * @var string[] + */ private $dangerDefaultStyleList = [ 'Not Held', 'Closed Lost', 'Dead', ]; + /** + * + * @var array< + * string, + * array< + * string, + * array{ + * actualList: string[], + * notActualList: string[], + * fieldType: string, + * } + * > + * > + */ private $auditedFieldsCache = []; private $entityManager; @@ -153,6 +179,9 @@ class Stream $this->recordServiceContainer = $recordServiceContainer; } + /** + * @return array + */ private function getStatusStyles(): array { if (empty($this->statusStyles)) { @@ -162,6 +191,9 @@ class Stream return $this->statusStyles; } + /** + * @return array + */ private function getStatusFields(): array { if (is_null($this->statusFields)) { @@ -200,6 +232,9 @@ class Stream return $isFollowed; } + /** + * @param string[] $sourceUserIdList + */ public function followEntityMass(Entity $entity, array $sourceUserIdList, bool $skipAclCheck = false): void { if (!$this->metadata->get(['scopes', $entity->getEntityType(), 'stream'])) { @@ -369,9 +404,21 @@ class Stream $this->entityManager->getQueryExecutor()->execute($delete); } - public function findUserStream(string $userId, array $params = []): stdClass + /** + * @param array{ + * offset?: int|null, + * maxSize: int|null, + * skipOwn?: bool, + * where?: ?array, + * after?: ?string, + * filter?: ?string, + * } $params + * @throws NotFound + * @throws Forbidden + */ + public function findUserStream(string $userId, array $params): stdClass { - $offset = intval($params['offset']); + $offset = intval($params['offset'] ?? 0); $maxSize = intval($params['maxSize']); $sqLimit = $offset + $maxSize + 1; @@ -834,6 +881,17 @@ class Stream ]; } + /** + * @param array{ + * offset?: int|null, + * maxSize: int|null, + * skipOwn?: bool, + * where?: ?array, + * after?: ?string, + * filter?: ?string, + * } $params + * @return array + */ private function getUserStreamWhereClause(array $params, User $user): array { $whereClause = []; @@ -915,7 +973,19 @@ class Stream } } - public function find(string $scope, ?string $id, array $params = []): stdClass + /** + * @param array{ + * offset?: int|null, + * maxSize: int|null, + * skipOwn?: bool, + * where?: ?array, + * after?: ?string, + * filter?: ?string, + * } $params + * @throws NotFound + * @throws Forbidden + */ + public function find(string $scope, ?string $id, array $params): stdClass { if ($scope === 'User') { if (empty($id)) { @@ -1258,7 +1328,7 @@ class Stream $note->set('usersIds', $userIdList); } - public function noteEmailReceived(Entity $entity, Email $email, $isInitial = false): void + public function noteEmailReceived(Entity $entity, Email $email, bool $isInitial = false): void { $entityType = $entity->getEntityType(); @@ -1385,6 +1455,9 @@ class Stream $this->entityManager->saveEntity($note); } + /** + * @param array $options + */ public function noteCreate(Entity $entity, array $options = []): void { $entityType = $entity->getEntityType(); @@ -1438,6 +1511,9 @@ class Stream $this->entityManager->saveEntity($note, $o); } + /** + * @param mixed $value + */ private function getStatusStyle(string $entityType, string $field, $value): string { $style = $this->metadata->get(['entityDefs', $entityType, 'fields', $field, 'style', $value]); @@ -1463,6 +1539,9 @@ class Stream return 'default'; } + /** + * @param array $options + */ public function noteCreateRelated( Entity $entity, string $parentType, @@ -1498,6 +1577,9 @@ class Stream $this->entityManager->saveEntity($note, $o); } + /** + * @param array $options + */ public function noteRelate(Entity $entity, string $parentType, string $parentId, array $options = []): void { $entityType = $entity->getEntityType(); @@ -1539,6 +1621,9 @@ class Stream $this->entityManager->saveEntity($note, $o); } + /** + * @param array $options + */ public function noteAssign(Entity $entity, array $options = []): void { $note = $this->entityManager->getEntity('Note'); @@ -1583,7 +1668,10 @@ class Stream $this->entityManager->saveEntity($note, $o); } - public function noteStatus(Entity $entity, $field, array $options = []): void + /** + * @param array $options + */ + public function noteStatus(Entity $entity, string $field, array $options = []): void { $note = $this->entityManager->getEntity('Note'); @@ -1623,6 +1711,16 @@ class Stream $this->entityManager->saveEntity($note, $o); } + /** + * @return array< + * string, + * array{ + * actualList: string[], + * notActualList: string[], + * fieldType: string, + * } + * > + */ private function getAuditedFieldsData(Entity $entity): array { $entityType = $entity->getEntityType(); @@ -1662,7 +1760,10 @@ class Stream return $this->auditedFieldsCache[$entityType]; } - public function handleAudited($entity, array $options = []): void + /** + * @param array $options + */ + public function handleAudited(Entity $entity, array $options = []): void { $auditedFields = $this->getAuditedFieldsData($entity); @@ -1762,6 +1863,9 @@ class Stream return $idList; } + /** + * @return RecordCollection + */ public function findEntityFollowers(Entity $entity, SearchParams $searchParams): RecordCollection { $builder = $this->selectBuilderFactory @@ -1788,6 +1892,7 @@ class Stream $query = $builder->build(); + /** @var \Espo\ORM\Collection */ $collection = $this->entityManager ->getRDBRepository('User') ->clone($query) @@ -1804,10 +1909,17 @@ class Stream $userService->prepareEntityForOutput($e); } + /** @var RecordCollection */ return new RecordCollection($collection, $total); } - public function getEntityFollowers(Entity $entity, $offset = 0, $limit = false): array + /** + * @return array{ + * idList: string[], + * nameMap: stdClass, + * } + */ + public function getEntityFollowers(Entity $entity, int $offset = 0, ?int $limit = null): array { if (!$limit) { $limit = 200; @@ -1837,7 +1949,7 @@ class Stream $data = [ 'idList' => [], - 'nameMap' => (object) [] + 'nameMap' => (object) [], ]; foreach ($userList as $user) { @@ -1850,6 +1962,9 @@ class Stream return $data; } + /** + * @return string[] + */ private function getOnlyTeamEntityTypeList(User $user): array { if ($user->isPortal()) { @@ -1883,6 +1998,9 @@ class Stream return $list; } + /** + * @return string[] + */ private function getOnlyOwnEntityTypeList(User $user): array { if ($user->isPortal()) { @@ -1926,6 +2044,9 @@ class Stream } } + /** + * @return string[] + */ private function getNotAllEntityTypeList(User $user): array { if (!$user->isPortal()) { @@ -1961,6 +2082,9 @@ class Stream return $list; } + /** + * @return string[] + */ private function getIgnoreScopeList(User $user): array { $ignoreScopeList = []; @@ -2196,6 +2320,18 @@ class Stream } } + /** + * @param array{ + * teamsAttributeIsChanged: bool, + * usersAttributeIsChanged: bool, + * forceProcessNoteNotifications: bool, + * teamIdList: string[], + * userIdList: string[], + * notificationThreshold: \DateTimeInterface, + * aclThreshold: \DateTimeInterface, + * } $params + * @return void + */ private function processNoteAclItem(Entity $entity, NoteEntity $note, array $params): void { $teamsAttributeIsChanged = $params['teamsAttributeIsChanged']; diff --git a/application/Espo/Services/Team.php b/application/Espo/Services/Team.php index 93f5ecec49..adb61d2d72 100644 --- a/application/Espo/Services/Team.php +++ b/application/Espo/Services/Team.php @@ -52,7 +52,7 @@ class Team extends Record implements } } - protected function clearRolesCache() + protected function clearRolesCache(): void { $this->fileManager->removeInDir('data/cache/application/acl'); $this->fileManager->removeInDir('data/cache/application/aclMap'); diff --git a/application/Espo/Services/User.php b/application/Espo/Services/User.php index f9ecf2eeb0..fd2eb58af0 100644 --- a/application/Espo/Services/User.php +++ b/application/Espo/Services/User.php @@ -72,14 +72,23 @@ class User extends Record implements use Di\FileManagerSetter; use Di\DataManagerSetter; + /** + * @var string[] + */ protected $mandatorySelectAttributeList = [ 'isActive', 'userName', 'type', ]; + /** + * @var string[] + */ protected $validateSkipFieldList = ['name', "firstName", "lastName"]; + /** + * @var string[] + */ protected $allowedUserTypeList = ['regular', 'admin', 'portal', 'api']; public function getEntity(?string $id = null): ?Entity @@ -247,10 +256,10 @@ class User extends Record implements ]; } - public function removeChangePasswordRequestJob($data) + public function removeChangePasswordRequestJob(stdClass $data): void { if (empty($data->id)) { - return false; + return; } $id = $data->id; @@ -260,11 +269,9 @@ class User extends Record implements if ($p) { $this->getEntityManager()->removeEntity($p); } - - return true; } - protected function hashPassword($password) + protected function hashPassword(string $password): string { $passwordHash = $this->injectableFactory->create(PasswordHash::class); @@ -550,7 +557,7 @@ class User extends Record implements return $this->injectableFactory->create(PasswordHash::class); } - protected function getInternalUserCount() + protected function getInternalUserCount(): int { return $this->getEntityManager() ->getRDBRepository('User') @@ -562,7 +569,7 @@ class User extends Record implements ->count(); } - protected function getPortalUserCount() + protected function getPortalUserCount(): int { return $this->getEntityManager() ->getRDBRepository('User') @@ -875,7 +882,7 @@ class User extends Record implements } } - protected function clearRoleCache(string $id) + protected function clearRoleCache(string $id): void { $this->fileManager->removeFile('data/cache/application/acl/' . $id . '.php'); $this->fileManager->removeFile('data/cache/application/aclMap/' . $id . '.php'); @@ -883,7 +890,7 @@ class User extends Record implements $this->dataManager->updateCacheTimestamp(); } - protected function clearPortalRolesCache() + protected function clearPortalRolesCache(): void { $this->fileManager->removeInDir('data/cache/application/aclPortal'); $this->fileManager->removeInDir('data/cache/application/aclPortalMap'); diff --git a/application/Espo/Services/Webhook.php b/application/Espo/Services/Webhook.php index 34804d28ce..fddb31fbe2 100644 --- a/application/Espo/Services/Webhook.php +++ b/application/Espo/Services/Webhook.php @@ -45,6 +45,9 @@ class Webhook extends Record implements const WEBHOOK_MAX_COUNT_PER_USER = 50; + /** + * @var string[] + */ protected $eventTypeList = [ 'create', 'update', @@ -52,8 +55,14 @@ class Webhook extends Record implements 'fieldUpdate', ]; + /** + * @var string[] + */ protected $onlyAdminAttributeList = ['userId', 'userName']; + /** + * @var string[] + */ protected $readOnlyAttributeList = ['secretKey']; public function populateDefaults(Entity $entity, stdClass $data): void @@ -93,7 +102,7 @@ class Webhook extends Record implements } } - protected function checkMaxCount() + protected function checkMaxCount(): void { $maxCount = $this->getConfig()->get('webhookMaxCountPerUser', self::WEBHOOK_MAX_COUNT_PER_USER); @@ -115,7 +124,7 @@ class Webhook extends Record implements $this->processEntityEventData($entity); } - protected function checkEntityUserIsApi(Entity $entity) + protected function checkEntityUserIsApi(Entity $entity): void { $userId = $entity->get('userId'); @@ -131,7 +140,7 @@ class Webhook extends Record implements } } - protected function processEntityEventData(Entity $entity) + protected function processEntityEventData(Entity $entity): void { $event = $entity->get('event');