New UserApi methods for getting single user from API. Some refactoring. New API exceptions.
This commit is contained in:
parent
23b51ea98c
commit
c3191d82e6
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Service\Exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidResponseException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Service\Exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotFoundException extends ApiException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $login;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
* @param int $userId
|
||||||
|
*/
|
||||||
|
public function __construct($message = 'User not found', $code = 0, \Exception $previous = null, $userId = null, $login = null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
$this->userId = $userId;
|
||||||
|
$this->login = $login;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ID of user which was not found
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getUserId()
|
||||||
|
{
|
||||||
|
return $this->userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLogin()
|
||||||
|
{
|
||||||
|
return $this->login;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,19 +5,19 @@ namespace Skobkin\Bundle\PointToolsBundle\Service;
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Guzzle\Http\Exception\ClientErrorResponseException;
|
||||||
use Guzzle\Service\Client;
|
use Guzzle\Service\Client;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\ApiException;
|
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\ApiException;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\UserNotFoundException;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Point.im user API functions from /api/user/*
|
* Basic Point.im user API functions from /api/user/*
|
||||||
*/
|
*/
|
||||||
class UserApi extends AbstractApi
|
class UserApi extends AbstractApi
|
||||||
{
|
{
|
||||||
const PATH_USER_INFO = '/api/user/%s';
|
|
||||||
const PATH_USER_SUBSCRIPTIONS = '/api/user/%s/subscriptions';
|
|
||||||
const PATH_USER_SUBSCRIBERS = '/api/user/%s/subscribers';
|
|
||||||
|
|
||||||
const AVATAR_SIZE_SMALL = '24';
|
const AVATAR_SIZE_SMALL = '24';
|
||||||
const AVATAR_SIZE_MEDIUM = '40';
|
const AVATAR_SIZE_MEDIUM = '40';
|
||||||
const AVATAR_SIZE_LARGE = '80';
|
const AVATAR_SIZE_LARGE = '80';
|
||||||
|
@ -25,7 +25,7 @@ class UserApi extends AbstractApi
|
||||||
/**
|
/**
|
||||||
* @var string Base URL for user avatars
|
* @var string Base URL for user avatars
|
||||||
*/
|
*/
|
||||||
protected $avatarsBaseUrl = 'point.im/avatar/';
|
protected $avatarsBaseUrl = '//point.im/avatar/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var EntityManager
|
* @var EntityManager
|
||||||
|
@ -50,21 +50,33 @@ class UserApi extends AbstractApi
|
||||||
*
|
*
|
||||||
* @param string $login
|
* @param string $login
|
||||||
* @return User[]
|
* @return User[]
|
||||||
|
* @throws ApiException
|
||||||
|
* @throws InvalidResponseException
|
||||||
|
* @throws UserNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getUserSubscribersByLogin($login)
|
public function getUserSubscribersByLogin($login)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$usersList = $this->getGetRequestData('/api/user/'.$login.'/subscribers', [], true);
|
$usersList = $this->getGetRequestData('/api/user/'.$login.'/subscribers', [], true);
|
||||||
|
} catch (ClientErrorResponseException $e) {
|
||||||
|
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
|
||||||
|
throw new UserNotFoundException('User not found', 0, $e, null, $login);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$users = $this->getUsersFromList($usersList);
|
return $this->getUsersFromList($usersList);
|
||||||
|
|
||||||
return $users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get user subscribers by user id
|
* Get user subscribers by user id
|
||||||
*
|
*
|
||||||
* @param int $id
|
* @param $id
|
||||||
* @return User[]
|
* @return User[]
|
||||||
|
* @throws ApiException
|
||||||
|
* @throws InvalidResponseException
|
||||||
|
* @throws UserNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getUserSubscribersById($id)
|
public function getUserSubscribersById($id)
|
||||||
{
|
{
|
||||||
|
@ -72,11 +84,17 @@ class UserApi extends AbstractApi
|
||||||
throw new \InvalidArgumentException('$id must be an integer');
|
throw new \InvalidArgumentException('$id must be an integer');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscribers', [], true);
|
$usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscribers', [], true);
|
||||||
|
} catch (ClientErrorResponseException $e) {
|
||||||
|
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
|
||||||
|
throw new UserNotFoundException('User not found', 0, $e, $id);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$users = $this->getUsersFromList($usersList);
|
return $this->getUsersFromList($usersList);
|
||||||
|
|
||||||
return $users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,21 +102,33 @@ class UserApi extends AbstractApi
|
||||||
*
|
*
|
||||||
* @param string $login
|
* @param string $login
|
||||||
* @return User[]
|
* @return User[]
|
||||||
|
* @throws ApiException
|
||||||
|
* @throws InvalidResponseException
|
||||||
|
* @throws UserNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getUserSubscriptionsByLogin($login)
|
public function getUserSubscriptionsByLogin($login)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$usersList = $this->getGetRequestData('/api/user/'.$login.'/subscriptions', [], true);
|
$usersList = $this->getGetRequestData('/api/user/'.$login.'/subscriptions', [], true);
|
||||||
|
} catch (ClientErrorResponseException $e) {
|
||||||
|
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
|
||||||
|
throw new UserNotFoundException('User not found', 0, $e, null, $login);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$users = $this->getUsersFromList($usersList);
|
return $this->getUsersFromList($usersList);
|
||||||
|
|
||||||
return $users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get user subscriptions by user id
|
* Get user subscriptions by user id
|
||||||
*
|
*
|
||||||
* @param int $id
|
* @param $id
|
||||||
* @return User[]
|
* @return User[]
|
||||||
|
* @throws ApiException
|
||||||
|
* @throws InvalidResponseException
|
||||||
|
* @throws UserNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getUserSubscriptionsById($id)
|
public function getUserSubscriptionsById($id)
|
||||||
{
|
{
|
||||||
|
@ -106,15 +136,97 @@ class UserApi extends AbstractApi
|
||||||
throw new \InvalidArgumentException('$id must be an integer');
|
throw new \InvalidArgumentException('$id must be an integer');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscriptions', [], true);
|
$usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscriptions', [], true);
|
||||||
|
} catch (ClientErrorResponseException $e) {
|
||||||
|
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
|
||||||
|
throw new UserNotFoundException('User not found', 0, $e, $id);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$users = $this->getUsersFromList($usersList);
|
return $this->getUsersFromList($usersList);
|
||||||
|
|
||||||
return $users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get user by id
|
||||||
|
*
|
||||||
|
* @param $id
|
||||||
|
* @return User
|
||||||
|
* @throws UserNotFoundException
|
||||||
|
* @throws ClientErrorResponseException
|
||||||
|
*/
|
||||||
|
public function getUserById($id)
|
||||||
|
{
|
||||||
|
if (!is_numeric($id)) {
|
||||||
|
throw new \InvalidArgumentException('$id must be an integer');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$userInfo = $this->getGetRequestData('/api/user/id/'.(int) $id, [], true);
|
||||||
|
} catch (ClientErrorResponseException $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)
|
||||||
|
{
|
||||||
|
if (!is_array($userInfo)) {
|
||||||
|
throw new \InvalidArgumentException('$userInfo must be an array');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var EntityRepository $userRepo */
|
||||||
|
$userRepo = $this->em->getRepository('SkobkinPointToolsBundle:User');
|
||||||
|
|
||||||
|
// @todo Return ID existance check when @ap-Codkelden will fix this API behaviour
|
||||||
|
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 = $userRepo->find($userInfo['id']))) {
|
||||||
|
// Creating new user
|
||||||
|
$user = new User($userInfo['id']);
|
||||||
|
$this->em->persist($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updating data
|
||||||
|
$user
|
||||||
|
->setLogin($userInfo['login'])
|
||||||
|
->setName($userInfo['name'])
|
||||||
|
;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->em->flush($user);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new ApiException(sprintf('Error while flushing changes for [%d] %s: %s', $user->getId(), $user->getLogin(), $e->getMessage()), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
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[]
|
* @return User[]
|
||||||
|
* @throws ApiException
|
||||||
|
* @throws InvalidResponseException
|
||||||
*/
|
*/
|
||||||
private function getUsersFromList(array $users = [])
|
private function getUsersFromList(array $users = [])
|
||||||
{
|
{
|
||||||
|
@ -125,44 +237,33 @@ class UserApi extends AbstractApi
|
||||||
/** @var EntityRepository $userRepo */
|
/** @var EntityRepository $userRepo */
|
||||||
$userRepo = $this->em->getRepository('SkobkinPointToolsBundle:User');
|
$userRepo = $this->em->getRepository('SkobkinPointToolsBundle:User');
|
||||||
|
|
||||||
|
/** @var User[] $resultUsers */
|
||||||
$resultUsers = [];
|
$resultUsers = [];
|
||||||
|
|
||||||
foreach ($users as $userData) {
|
foreach ($users as $userInfo) {
|
||||||
if (array_key_exists('id', $userData) && array_key_exists('login', $userData) && array_key_exists('name', $userData) && is_numeric($userData['id'])) {
|
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
|
// @todo Optimize with prehashed id's list
|
||||||
$user = $userRepo->findOneBy(['id' => $userData['id']]);
|
if (null === ($user = $userRepo->find($userInfo['id']))) {
|
||||||
|
$user = new User((int) $userInfo['id']);
|
||||||
if (!$user) {
|
|
||||||
$user = new User();
|
|
||||||
$user
|
|
||||||
->setId((int) $userData['id'])
|
|
||||||
->setLogin($userData['login'])
|
|
||||||
;
|
|
||||||
$this->em->persist($user);
|
$this->em->persist($user);
|
||||||
|
|
||||||
try {
|
|
||||||
$this->em->flush();
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
throw new ApiException(sprintf('Error while flushing new user [%d] %s: %s', $user->getId(), $user->getLogin(), $e->getMessage()), 0, $e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating data
|
// Updating data
|
||||||
if ($user->getLogin() !== $userData['login']) {
|
$user
|
||||||
$user->setLogin($userData['login']);
|
->setLogin($userInfo['login'])
|
||||||
}
|
->setName($userInfo['name'])
|
||||||
if ($user->getName() !== $userData['name']) {
|
;
|
||||||
$user->setName($userData['name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->em->flush();
|
$this->em->flush($user);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw new ApiException(sprintf('Error while flushing changes for [%d] %s: %s', $user->getId(), $user->getLogin(), $e->getMessage()), 0, $e);
|
throw new ApiException(sprintf('Error while flushing changes for [%d] %s: %s', $user->getId(), $user->getLogin(), $e->getMessage()), 0, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
$resultUsers[] = $user;
|
$resultUsers[] = $user;
|
||||||
|
} else {
|
||||||
|
throw new InvalidResponseException('Invalid API response. Mandatory fields do not exist.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,10 +271,18 @@ class UserApi extends AbstractApi
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $login
|
* Creates avatar with specified size URL for user
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @param int $size
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getAvatarUrl(User $user, $size)
|
public function getAvatarUrl(User $user, $size)
|
||||||
{
|
{
|
||||||
return ($this->useHttps ? 'https://' : 'http://') . $this->avatarsBaseUrl . $user->getLogin() . '/' . $size;
|
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.$user->getLogin().'/'.$size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue