diff --git a/application/Espo/Core/Repositories/Database.php b/application/Espo/Core/Repositories/Database.php index fda09ebbd6..bf4ce6de75 100644 --- a/application/Espo/Core/Repositories/Database.php +++ b/application/Espo/Core/Repositories/Database.php @@ -50,7 +50,8 @@ use Espo\Core\{ }; /** - * The default repository used for all entities. + * @template T of \Espo\Core\ORM\Entity + * @extends RDBRepository<\Espo\Core\ORM\Entity> */ class Database extends RDBRepository { @@ -116,6 +117,9 @@ class Database extends RDBRepository { } + /** + * @phpstan-param T $entity + */ public function save(Entity $entity, array $options = []): void { if ( @@ -135,6 +139,9 @@ class Database extends RDBRepository parent::save($entity, $options); } + /** + * @phpstan-param T $entity + */ protected function beforeRemove(Entity $entity, array $options = []) { parent::beforeRemove($entity, $options); @@ -156,6 +163,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ protected function afterRemove(Entity $entity, array $options = []) { parent::afterRemove($entity, $options); @@ -165,6 +175,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ protected function afterMassRelate(Entity $entity, $relationName, array $params = [], array $options = []) { if ($this->hooksDisabled || !empty($options['skipHooks'])) { @@ -185,6 +198,9 @@ class Database extends RDBRepository ); } + /** + * @phpstan-param T $entity + */ protected function afterRelate(Entity $entity, $relationName, $foreign, $data = null, array $options = []) { parent::afterRelate($entity, $relationName, $foreign, $data, $options); @@ -216,6 +232,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ protected function afterUnrelate(Entity $entity, $relationName, $foreign, array $options = []) { parent::afterUnrelate($entity, $relationName, $foreign, $options); @@ -242,6 +261,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ protected function beforeSave(Entity $entity, array $options = []) { parent::beforeSave($entity, $options); @@ -251,6 +273,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ protected function afterSave(Entity $entity, array $options = []) { if (!empty($this->restoreData)) { @@ -266,6 +291,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ private function processCreatedAndModifiedFieldsSave(Entity $entity, array $options): void { if ($entity->isNew()) { @@ -295,6 +323,9 @@ class Database extends RDBRepository } } + /** + * @phpstan-param T $entity + */ private function processCreatedAndModifiedFieldsSaveNew(Entity $entity, array $options): void { $nowString = DateTimeUtil::getSystemNowString(); @@ -325,6 +356,7 @@ class Database extends RDBRepository } /** + * @phpstan-param T $entity * @return mixed */ private function getAttributeParam(Entity $entity, string $attribute, string $param) @@ -345,6 +377,7 @@ class Database extends RDBRepository } /** + * @phpstan-param T $entity * @return mixed */ private function getRelationParam(Entity $entity, string $relation, string $param) diff --git a/application/Espo/Entities/Preferences.php b/application/Espo/Entities/Preferences.php index 08840ac0e0..07d1dc66dd 100644 --- a/application/Espo/Entities/Preferences.php +++ b/application/Espo/Entities/Preferences.php @@ -36,16 +36,20 @@ class Preferences extends \Espo\Core\ORM\Entity public function getSmtpParams(): ?array { $smtpParams = []; + $smtpParams['server'] = $this->get('smtpServer'); + if ($smtpParams['server']) { $smtpParams['port'] = $this->get('smtpPort'); $smtpParams['server'] = $this->get('smtpServer'); $smtpParams['auth'] = $this->get('smtpAuth'); $smtpParams['security'] = $this->get('smtpSecurity'); + if ($this->get('smtpAuth')) { $smtpParams['username'] = $this->get('smtpUsername'); $smtpParams['password'] = $this->get('smtpPassword'); } + return $smtpParams; } diff --git a/application/Espo/ORM/Repository/RDBRepository.php b/application/Espo/ORM/Repository/RDBRepository.php index c332ac0269..fe7afb5d79 100644 --- a/application/Espo/ORM/Repository/RDBRepository.php +++ b/application/Espo/ORM/Repository/RDBRepository.php @@ -48,6 +48,10 @@ use stdClass; use RuntimeException; use PDO; +/** + * @template T of Entity + * @implements Repository + */ class RDBRepository implements Repository { protected $entityType; diff --git a/application/Espo/ORM/Repository/Repository.php b/application/Espo/ORM/Repository/Repository.php index 76fa125269..97ac209f5f 100644 --- a/application/Espo/ORM/Repository/Repository.php +++ b/application/Espo/ORM/Repository/Repository.php @@ -33,26 +33,36 @@ use Espo\ORM\Entity; /** * An access point for fetching and storing records. + * + * @template T of Entity */ interface Repository { /** * Get a new entity. + * + * @phpstan-return T */ public function getNew(): Entity; /** * Fetch an entity by ID. + * + * @phpstan-return ?T */ public function getById(string $id): ?Entity; /** * Store an entity. + * + * @phpstan-param T $entity */ public function save(Entity $entity, array $options = []): void; /** * Remove an entity. + * + * @phpstan-param T $entity */ public function remove(Entity $entity, array $options = []): void; } diff --git a/application/Espo/Repositories/EmailAddress.php b/application/Espo/Repositories/EmailAddress.php index 6674ec5eaf..30aa5f5f6c 100644 --- a/application/Espo/Repositories/EmailAddress.php +++ b/application/Espo/Repositories/EmailAddress.php @@ -75,7 +75,7 @@ class EmailAddress extends \Espo\Core\Repositories\Database implements $exist = []; foreach ($eaCollection as $ea) { - $ids[] = $ea->id; + $ids[] = $ea->getId(); $exist[] = $ea->get('lower'); } @@ -93,7 +93,7 @@ class EmailAddress extends \Espo\Core\Repositories\Database implements $this->save($ea); - $ids[] = $ea->id; + $ids[] = $ea->getId(); } } } @@ -115,7 +115,7 @@ class EmailAddress extends \Espo\Core\Repositories\Database implements ] ) ->where([ - 'ee.entityId' => $entity->id, + 'ee.entityId' => $entity->getId(), 'ee.entityType' => $entity->getEntityType(), 'ee.deleted' => false, ]) @@ -159,7 +159,7 @@ class EmailAddress extends \Espo\Core\Repositories\Database implements $where[] = [ 'OR' => [ 'entityType!=' => $exceptionEntity->getEntityType(), - 'entityId!=' => $exceptionEntity->id, + 'entityId!=' => $exceptionEntity->getId(), ] ]; } diff --git a/application/Espo/Repositories/LayoutSet.php b/application/Espo/Repositories/LayoutSet.php index d893067c34..d61fe7ff9a 100644 --- a/application/Espo/Repositories/LayoutSet.php +++ b/application/Espo/Repositories/LayoutSet.php @@ -44,9 +44,9 @@ class LayoutSet extends \Espo\Core\Repositories\Database foreach ($listBefore as $name) { if (!in_array($name, $listNow)) { $layout = $this->entityManager - ->getRepository('LayoutRecord') + ->getRDBRepository('LayoutRecord') ->where([ - 'layoutSetId' => $entity->id, + 'layoutSetId' => $entity->getId(), 'name' => $name, ]) ->findOne(); @@ -62,9 +62,9 @@ class LayoutSet extends \Espo\Core\Repositories\Database protected function afterRemove(Entity $entity, array $options = []) { $layoutList = $this->entityManager - ->getRepository('LayoutRecord') + ->getRDBRepository('LayoutRecord') ->where([ - 'layoutSetId' => $entity->id, + 'layoutSetId' => $entity->getId(), ]) ->find(); diff --git a/application/Espo/Repositories/PhoneNumber.php b/application/Espo/Repositories/PhoneNumber.php index 6960b80cb0..d8c4b239eb 100644 --- a/application/Espo/Repositories/PhoneNumber.php +++ b/application/Espo/Repositories/PhoneNumber.php @@ -67,7 +67,7 @@ class PhoneNumber extends Database implements $exist = []; foreach ($phoneNumbers as $phoneNumber) { - $ids[] = $phoneNumber->id; + $ids[] = $phoneNumber->getId(); $exist[] = $phoneNumber->get('name'); } @@ -85,7 +85,7 @@ class PhoneNumber extends Database implements $this->save($phoneNumber); - $ids[] = $phoneNumber->id; + $ids[] = $phoneNumber->getId(); } } } @@ -107,7 +107,7 @@ class PhoneNumber extends Database implements ] ) ->where([ - 'en.entityId' => $entity->id, + 'en.entityId' => $entity->getId(), 'en.entityType' => $entity->getEntityType(), 'en.deleted' => false, ]) @@ -146,13 +146,13 @@ class PhoneNumber extends Database implements $where[] = [ 'OR' => [ 'entityType!=' => $exceptionEntity->getEntityType(), - 'entityId!=' => $exceptionEntity->id, + 'entityId!=' => $exceptionEntity->getId(), ] ]; } $itemList = $this->entityManager - ->getRepository('EntityPhoneNumber') + ->getRDBRepository('EntityPhoneNumber') ->sth() ->select(['entityType', 'entityId']) ->where($where) @@ -192,7 +192,8 @@ class PhoneNumber extends Database implements $where[] = ['entityType' => $entityType]; } - $itemList = $this->entityManager->getRepository('EntityPhoneNumber') + $itemList = $this->entityManager + ->getRDBRepository('EntityPhoneNumber') ->sth() ->select(['entityType', 'entityId']) ->where($where) diff --git a/application/Espo/Repositories/Portal.php b/application/Espo/Repositories/Portal.php index b0090ec8b2..efdcf8d3e1 100644 --- a/application/Espo/Repositories/Portal.php +++ b/application/Espo/Repositories/Portal.php @@ -52,7 +52,7 @@ class Portal extends Database implements $url = $siteUrl . 'portal/'; - if ($entity->id === $this->config->get('defaultPortalId')) { + if ($entity->getId() === $this->config->get('defaultPortalId')) { $entity->set('isDefault', true); $entity->setFetched('isDefault', true); } @@ -60,7 +60,7 @@ class Portal extends Database implements if ($entity->get('customId')) { $url .= $entity->get('customId') . '/'; } else { - $url .= $entity->id . '/'; + $url .= $entity->getId() . '/'; } $entity->set('isDefault', false); diff --git a/application/Espo/Repositories/Preferences.php b/application/Espo/Repositories/Preferences.php index 689aad194c..c0d7d51128 100644 --- a/application/Espo/Repositories/Preferences.php +++ b/application/Espo/Repositories/Preferences.php @@ -35,10 +35,16 @@ use Espo\ORM\EntityFactory; use Espo\ORM\Repository\Repository; use Espo\Core\Utils\Json; +use Espo\Entities\Preferences as PreferencesEntity; +use Espo\Entities\User; + use stdClass; use Espo\Core\Di; +/** + * @implements Repository + */ class Preferences implements Repository, Di\MetadataAware, @@ -75,9 +81,10 @@ class Preferences implements Repository, public function getById(string $id): ?Entity { + /** @var PreferencesEntity $entity */ $entity = $this->entityFactory->create('Preferences'); - $entity->id = $id; + $entity->set('id', $id); if (!isset($this->data[$id])) { $this->loadData($id); @@ -160,9 +167,9 @@ class Preferences implements Repository, $this->data[$id] = $defaults; } - protected function fetchAutoFollowEntityTypeList(Entity $entity) + protected function fetchAutoFollowEntityTypeList(PreferencesEntity $entity) { - $id = $entity->id; + $id = $entity->getId(); $autoFollowEntityTypeList = []; @@ -179,12 +186,13 @@ class Preferences implements Repository, } $this->data[$id]['autoFollowEntityTypeList'] = $autoFollowEntityTypeList; + $entity->set('autoFollowEntityTypeList', $autoFollowEntityTypeList); } protected function storeAutoFollowEntityTypeList(Entity $entity) { - $id = $entity->id; + $id = $entity->getId(); if (!$entity->isAttributeChanged('autoFollowEntityTypeList')) { return; @@ -192,7 +200,8 @@ class Preferences implements Repository, $entityTypeList = $entity->get('autoFollowEntityTypeList') ?? []; - $delete = $this->entityManager->getQueryBuilder() + $delete = $this->entityManager + ->getQueryBuilder() ->delete() ->from('Autofollow') ->where([ @@ -216,17 +225,17 @@ class Preferences implements Repository, public function save(Entity $entity, array $options = []): void { - if (!$entity->id) { + if (!$entity->getId()) { return; } - $this->data[$entity->id] = $entity->toArray(); + $this->data[$entity->getId()] = $entity->toArray(); $fields = $fields = $this->metadata->get('entityDefs.Preferences.fields'); $data = []; - foreach ($this->data[$entity->id] as $field => $value) { + foreach ($this->data[$entity->getId()] as $field => $value) { if (empty($fields[$field]['notStorable'])) { $data[$field] = $value; } @@ -239,7 +248,7 @@ class Preferences implements Repository, ->into('Preferences') ->columns(['id', 'data']) ->values([ - 'id' => $entity->id, + 'id' => $entity->getId(), 'data' => $dataString, ]) ->updateSet([ @@ -249,7 +258,8 @@ class Preferences implements Repository, $this->entityManager->getQueryExecutor()->execute($insert); - $user = $this->entityManager->getEntity('User', $entity->id); + /** @var User $user */ + $user = $this->entityManager->getEntity('User', $entity->getId()); if ($user && !$user->isPortal()) { $this->storeAutoFollowEntityTypeList($entity); @@ -271,14 +281,14 @@ class Preferences implements Repository, public function remove(Entity $entity, array $options = []): void { - if (!$entity->id) { + if (!$entity->getId()) { return; } - $this->deleteFromDb($entity->id); + $this->deleteFromDb($entity->getId()); - if (isset($this->data[$entity->id])) { - unset($this->data[$entity->id]); + if (isset($this->data[$entity->getId()])) { + unset($this->data[$entity->getId()]); } } diff --git a/application/Espo/Repositories/ScheduledJob.php b/application/Espo/Repositories/ScheduledJob.php index 689a0aa4af..2e90173a5a 100644 --- a/application/Espo/Repositories/ScheduledJob.php +++ b/application/Espo/Repositories/ScheduledJob.php @@ -43,7 +43,7 @@ class ScheduledJob extends \Espo\Core\Repositories\Database if ($entity->isAttributeChanged('scheduling')) { $jobList = $this->entityManager - ->getRepository('Job') + ->getRDBRepository('Job') ->where([ 'scheduledJobId' => $entity->id, 'status' => Status::PENDING, diff --git a/application/Espo/Repositories/User.php b/application/Espo/Repositories/User.php index afb5c7ff8c..bd0cfbf420 100644 --- a/application/Espo/Repositories/User.php +++ b/application/Espo/Repositories/User.php @@ -33,9 +33,15 @@ use Espo\ORM\Entity; use Espo\Core\Exceptions\Error; use Espo\Core\Exceptions\Conflict; - use Espo\Core\Repositories\Database; +use Espo\Repositories\UserData as UserDataRepository; +use Espo\Entities\UserData; + +/** + * @template T of \Espo\Entities\User + * @extends Database<\Espo\Entities\User> + */ class User extends Database { protected function beforeSave(Entity $entity, array $options = []) @@ -62,16 +68,16 @@ class User extends Database if ($entity->has('type') && !$entity->isPortal()) { $entity->set('portalRolesIds', []); - $entity->set('portalRolesNames', (object)[]); + $entity->set('portalRolesNames', (object) []); $entity->set('portalsIds', []); - $entity->set('portalsNames', (object)[]); + $entity->set('portalsNames', (object) []); } if ($entity->has('type') && $entity->isPortal()) { $entity->set('rolesIds', []); - $entity->set('rolesNames', (object)[]); + $entity->set('rolesNames', (object) []); $entity->set('teamsIds', []); - $entity->set('teamsNames', (object)[]); + $entity->set('teamsNames', (object) []); $entity->set('defaultTeamId', null); $entity->set('defaultTeamName', null); } @@ -137,7 +143,7 @@ class User extends Database { parent::afterRemove($entity, $options); - $userData = $this->entityManager->getRepository('UserData')->getByUserId($entity->id); + $userData = $this->getUserDataRepository()->getByUserId($entity->getId()); if ($userData) { $this->entityManager->removeEntity($userData); @@ -159,4 +165,9 @@ class User extends Database ]) ->findOne(); } + + private function getUserDataRepository(): UserDataRepository + { + return $this->entityManager->getRepository(UserData::ENTITY_TYPE); + } }