em = $entityManager; $this->serializer = $serializer; $this->userRepository = $this->em->getRepository('SkobkinPointToolsBundle:User'); } public function isAuthDataValid(string $login, string $password): bool { $auth = $this->authenticate($login, $password); if (null === $auth->getError() && null !== $auth->getToken()) { $this->logout($auth); return true; } return false; } public function authenticate(string $login, string $password): Auth { try { $authData = $this->getPostRequestData( '/api/login', [ 'login' => $login, 'password' => $password, ] ); return $this->serializer->deserialize($authData, Auth::class, 'json'); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new InvalidResponseException('API method not found', 0, $e); } else { throw $e; } } } public function logout(Auth $auth): bool { try { $this->getPostRequestData('/api/logout', ['csrf_token' => $auth->getCsRfToken()]); return true; } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new InvalidResponseException('API method not found', 0, $e); } elseif (Response::HTTP_FORBIDDEN === $e->getResponse()->getStatusCode()) { return true; } else { throw $e; } } } /** * Get user subscribers by user login * * @param string $login * * @return User[] * * @throws ApiException * @throws InvalidResponseException * @throws UserNotFoundException */ public function getUserSubscribersByLogin(string $login): array { try { $usersList = $this->getGetRequestData('/api/user/'.urlencode($login).'/subscribers', [], true); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new UserNotFoundException('User not found', 0, $e, null, $login); } else { throw $e; } } return $this->getUsersFromList($usersList); } /** * Get user subscribers by user id * * @param int $id * * @return User[] * * @throws ApiException * @throws InvalidResponseException * @throws UserNotFoundException */ public function getUserSubscribersById(int $id): array { try { $usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscribers', [], true); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new UserNotFoundException('User not found', 0, $e, $id); } else { throw $e; } } return $this->getUsersFromList($usersList); } /** * Get user subscriptions by user login * * @param string $login * * @return User[] * * @throws ApiException * @throws InvalidResponseException * @throws UserNotFoundException */ public function getUserSubscriptionsByLogin(string $login): array { try { $usersList = $this->getGetRequestData('/api/user/'.urlencode($login).'/subscriptions', [], true); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new UserNotFoundException('User not found', 0, $e, null, $login); } else { throw $e; } } return $this->getUsersFromList($usersList); } /** * Get user subscriptions by user id * * @param int $id * * @return User[] * * @throws ApiException * @throws InvalidResponseException * @throws UserNotFoundException */ public function getUserSubscriptionsById(int $id): array { try { $usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscriptions', [], true); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new UserNotFoundException('User not found', 0, $e, $id); } else { throw $e; } } return $this->getUsersFromList($usersList); } /** * Get single user by login * * @param string $login * * @return User * * @throws UserNotFoundException * @throws RequestException */ public function getUserByLogin(string $login): User { try { $userInfo = $this->getGetRequestData('/api/user/login/'.urlencode($login), [], true); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new UserNotFoundException('User not found', 0, $e, null, $login); } else { throw $e; } } return $this->getUserFromUserInfo($userInfo); } /** * Get single user by id * * @param int $id * * @return User * * @throws UserNotFoundException * @throws RequestException */ public function getUserById(int $id): User { try { $userInfo = $this->getGetRequestData('/api/user/id/'.$id, [], true); } catch (RequestException $e) { if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) { throw new UserNotFoundException('User not found', 0, $e, $id); } else { throw $e; } } return $this->getUserFromUserInfo($userInfo); } /** * Finds and updates or create new user from API response data * * @param array $userInfo * * @return User * * @throws ApiException * @throws InvalidResponseException */ public function getUserFromUserInfo(array $userInfo): User { // @todo Refactor to UserFactory->createFromArray() if (array_key_exists('id', $userInfo) && array_key_exists('login', $userInfo) && array_key_exists('name', $userInfo) && is_numeric($userInfo['id'])) { /** @var User $user */ if (null === ($user = $this->userRepository->find($userInfo['id']))) { // Creating new user $user = new User($userInfo['id']); $this->em->persist($user); } // Updating data $user ->setLogin($userInfo['login']) ->setName($userInfo['name']) ; return $user; } throw new InvalidResponseException('Invalid API response. Mandatory fields do not exist.'); } /** * Get array of User objects from API response containing user list * * @param array $users * * @return User[] * * @throws ApiException * @throws InvalidResponseException */ private function getUsersFromList(array $users = []): array { /** @var User[] $resultUsers */ $resultUsers = []; foreach ($users as $userInfo) { if (array_key_exists('id', $userInfo) && array_key_exists('login', $userInfo) && array_key_exists('name', $userInfo) && is_numeric($userInfo['id'])) { // @todo Optimize with prehashed id's list if (null === ($user = $this->userRepository->find($userInfo['id']))) { $user = new User((int) $userInfo['id']); $this->em->persist($user); } // Updating data $user ->setLogin($userInfo['login']) ->setName($userInfo['name']) ; $resultUsers[] = $user; } else { throw new InvalidResponseException('Invalid API response. Mandatory fields do not exist.'); } } return $resultUsers; } /** * Creates URL of avatar with specified size by User object * * @param User $user * @param string $size * * @return string */ public function getAvatarUrl(User $user, string $size): string { return $this->getAvatarUrlByLogin($user->getLogin(), $size); } /** * Creates URL of avatar with specified size by login string * * @param string $login * @param string $size * * @return string */ public function getAvatarUrlByLogin(string $login, string $size): string { if (!in_array($size, [self::AVATAR_SIZE_SMALL, self::AVATAR_SIZE_MEDIUM, self::AVATAR_SIZE_LARGE], true)) { throw new \InvalidArgumentException('Avatar size must be one of restricted variants. See UserApi class AVATAR_SIZE_* constants.'); } return $this->avatarsBaseUrl.urlencode($login).'/'.$size; } }