MisdGuzzleBundle removed from project in favor of CsaGuzzleBundle. AbstractApi refactored to use Guzzle 6. Service names refactoring (now all uses 'app.' prefix). Factories slightly refactored.

This commit is contained in:
Alexey Skobkin 2017-01-09 02:26:06 +03:00
parent 997f41e723
commit cf005637f8
21 changed files with 188 additions and 476 deletions

View file

@ -17,7 +17,6 @@ class AppKernel extends Kernel
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Misd\GuzzleBundle\MisdGuzzleBundle(),
new Csa\Bundle\GuzzleBundle\CsaGuzzleBundle(),
new Ob\HighchartsBundle\ObHighchartsBundle(),
new Knp\Bundle\MarkdownBundle\KnpMarkdownBundle(),

View file

@ -75,7 +75,7 @@ swiftmailer:
knp_markdown:
parser:
service: markdown.parser.point
service: app.point.markdown_parser
knp_paginator:
template:

View file

@ -18,7 +18,6 @@
"sensio/distribution-bundle": "~5.0",
"sensio/framework-extra-bundle": "^3.0.2",
"incenteev/composer-parameter-handler": "~2.0",
"misd/guzzle-bundle": "~1.0",
"ob/highcharts-bundle": "^1.2",
"doctrine/doctrine-migrations-bundle": "^1.0",
"jms/serializer-bundle": "^1.1",

171
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "db525f9a45b3f2ce9135fd75fb029dec",
"content-hash": "0ed6c570d9db8a02d84f65d8a5796f3e",
"packages": [
{
"name": "csa/guzzle-bundle",
@ -970,102 +970,6 @@
],
"time": "2016-12-18T15:42:34+00:00"
},
{
"name": "guzzle/guzzle",
"version": "v3.9.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle3.git",
"reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
"reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
"shasum": ""
},
"require": {
"ext-curl": "*",
"php": ">=5.3.3",
"symfony/event-dispatcher": "~2.1"
},
"replace": {
"guzzle/batch": "self.version",
"guzzle/cache": "self.version",
"guzzle/common": "self.version",
"guzzle/http": "self.version",
"guzzle/inflection": "self.version",
"guzzle/iterator": "self.version",
"guzzle/log": "self.version",
"guzzle/parser": "self.version",
"guzzle/plugin": "self.version",
"guzzle/plugin-async": "self.version",
"guzzle/plugin-backoff": "self.version",
"guzzle/plugin-cache": "self.version",
"guzzle/plugin-cookie": "self.version",
"guzzle/plugin-curlauth": "self.version",
"guzzle/plugin-error-response": "self.version",
"guzzle/plugin-history": "self.version",
"guzzle/plugin-log": "self.version",
"guzzle/plugin-md5": "self.version",
"guzzle/plugin-mock": "self.version",
"guzzle/plugin-oauth": "self.version",
"guzzle/service": "self.version",
"guzzle/stream": "self.version"
},
"require-dev": {
"doctrine/cache": "~1.3",
"monolog/monolog": "~1.0",
"phpunit/phpunit": "3.7.*",
"psr/log": "~1.0",
"symfony/class-loader": "~2.1",
"zendframework/zend-cache": "2.*,<2.3",
"zendframework/zend-log": "2.*,<2.3"
},
"suggest": {
"guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.9-dev"
}
},
"autoload": {
"psr-0": {
"Guzzle": "src/",
"Guzzle\\Tests": "tests/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Guzzle Community",
"homepage": "https://github.com/guzzle/guzzle/contributors"
}
],
"description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"abandoned": "guzzlehttp/guzzle",
"time": "2015-03-18T18:23:50+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.2.2",
@ -1856,79 +1760,6 @@
],
"time": "2016-10-29T18:58:20+00:00"
},
{
"name": "misd/guzzle-bundle",
"version": "v1.1.5",
"source": {
"type": "git",
"url": "https://github.com/misd-service-development/guzzle-bundle.git",
"reference": "555c105ef4ac66597a029fe634dee0fe4f9cb084"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/misd-service-development/guzzle-bundle/zipball/555c105ef4ac66597a029fe634dee0fe4f9cb084",
"reference": "555c105ef4ac66597a029fe634dee0fe4f9cb084",
"shasum": ""
},
"require": {
"guzzle/guzzle": "~3.0",
"php": ">=5.3.3",
"symfony/framework-bundle": "~2.2"
},
"conflict": {
"jms/serializer-bundle": "<0.11-dev",
"sensio/framework-extra-bundle": ">=4.0-dev"
},
"require-dev": {
"doctrine/cache": "~1.0",
"jms/serializer-bundle": "~0.11",
"phpunit/phpunit": "~4.3",
"sensio/framework-extra-bundle": "~2.2",
"symfony/monolog-bundle": "~2.2",
"symfony/yaml": "~2.2"
},
"suggest": {
"jms/serializer-bundle": "Serialize/deserialize objects to/from XML, JSON and YAML",
"sensio/framework-extra-bundle": "Provides a parameter converter",
"symfony/monolog-bundle": "Log requests"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Misd\\GuzzleBundle\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Wilkinson",
"email": "chris.wilkinson@admin.cam.ac.uk"
}
],
"description": "Integrates Guzzle into your Symfony2 application",
"homepage": "https://github.com/misd-service-development/guzzle-bundle",
"keywords": [
"Guzzle",
"api",
"bundle",
"client",
"curl",
"http",
"http client",
"rest",
"web service"
],
"abandoned": true,
"time": "2014-12-01T08:29:51+00:00"
},
{
"name": "monolog/monolog",
"version": "1.22.0",

View file

@ -37,7 +37,7 @@ class TelegramSetWebHookCommand extends ContainerAwareCommand
protected function execute(InputInterface $input, OutputInterface $output)
{
$container = $this->getContainer();
$telegramClient = $container->get('point_tools.telegram.api_client');
$telegramClient = $container->get('app.telegram.api_client');
if (self::MODE_SET === strtolower($input->getArgument('mode'))) {
if (!$input->hasArgument('host')) {

View file

@ -49,9 +49,9 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand
$log->info('UpdateSubscriptionsCommand started.');
/** @var UserApi $api */
$api = $this->getContainer()->get('skobkin_point_tools.api_user');
$api = $this->getContainer()->get('app.point.api_user');
/** @var SubscriptionsManager $subscriptionsManager */
$subscriptionsManager = $this->getContainer()->get('skobkin_point_tools.subscriptions_manager');
$subscriptionsManager = $this->getContainer()->get('app.point.subscriptions_manager');
try {
$serviceUserId = $this->getContainer()->getParameter('point_id');

View file

@ -24,7 +24,7 @@ class CrawlerController extends AbstractApiController
$page = $serializer->deserialize($json, 'Skobkin\Bundle\PointToolsBundle\DTO\Api\Crawler\PostsPage', 'json');
/** @var PostFactory $factory */
$factory = $this->get('skobkin__point_tools.service_factory.post_factory');
$factory = $this->get('app.point.post_factory');
$continue = $factory->createFromPageDTO($page);

View file

@ -28,7 +28,7 @@ class WebHookController extends Controller
);
try {
$this->get('point_tools.telegram.update_dispatcher')->process($update);
$this->get('app.telegram.update_dispatcher')->process($update);
} catch (\Exception $e) {
if ($this->getParameter('kernel.debug')) {
throw $e;

View file

@ -35,7 +35,7 @@ class UserController extends Controller
10
);
$userApi = $this->container->get('skobkin_point_tools.api_user');
$userApi = $this->container->get('app.point.api_user');
return $this->render('SkobkinPointToolsBundle:User:show.html.twig', [
'user' => $user,

View file

@ -1,83 +1,85 @@
services:
# Guzzle 6 client for Telegram
point_tools.http.telegram_client:
# HTTP client for Telegram
app.http.telegram_client:
class: GuzzleHttp\Client
arguments: [{ timeout: 3.0 }]
tags:
- { name: csa_guzzle.client }
# Guzzle 5 client for Point API
# TODO upgrade and remove misd bundle
skobkin_point_tools.http_client:
class: %guzzle.client.class%
arguments: [ "%point_base_url%" ]
# HTTP client for Point API
app.http.point_client:
class: GuzzleHttp\Client
arguments: [ { base_uri: "%point_base_url%", timeout: 5.0 } ]
tags:
- { name: guzzle.client }
- { name: csa_guzzle.client }
skobkin_point_tools.api_user:
# Point API clients
# Abstract API client with common dependency
app.point.abstract_api:
abstract: true
arguments: [@app.http.point_client]
app.point.api_user:
class: Skobkin\Bundle\PointToolsBundle\Service\UserApi
parent: app.point.abstract_api
arguments:
- @skobkin_point_tools.http_client
- "%point_use_https%"
- "%point_api_base_url%"
- @doctrine.orm.entity_manager
- @serializer
skobkin_point_tools.api_post:
app.point.api_post:
class: Skobkin\Bundle\PointToolsBundle\Service\PostApi
parent: app.point.abstract_api
arguments:
- @skobkin_point_tools.http_client
- "%point_use_https%"
- "%point_api_base_url%"
- @skobkin__point_tools.service_factory.post_factory
- @app.point.post_factory
skobkin_point_tools.subscriptions_manager:
# Point subscription manager
app.point.subscriptions_manager:
class: Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager
arguments: [ @doctrine.orm.entity_manager, @event_dispatcher ]
# Factories
# User factory
skobkin__point_tools.service_factory.user_factory:
app.point.user_factory:
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\UserFactory
arguments: [ @doctrine.orm.entity_manager ]
# Comment factory
skobkin__point_tools.service_factory.comment_factory:
app.point.comment_factory:
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\CommentFactory
arguments: [ @doctrine.orm.entity_manager, @skobkin__point_tools.service_factory.user_factory ]
arguments: [ @doctrine.orm.entity_manager, @app.point.user_factory ]
# Tag factory
skobkin__point_tools.service_factory.tag_factory:
app.point.tag_factory:
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\TagFactory
arguments: [ @logger, @doctrine.orm.entity_manager ]
# File factory
skobkin__point_tools.service_factory.file_factory:
app.point.file_factory:
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\FileFactory
arguments: [ @logger, @doctrine.orm.entity_manager ]
# Post factory
skobkin__point_tools.service_factory.post_factory:
app.point.post_factory:
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\PostFactory
arguments:
- @logger
- @doctrine.orm.entity_manager
- @skobkin__point_tools.service_factory.user_factory
- @skobkin__point_tools.service_factory.file_factory
- @skobkin__point_tools.service_factory.comment_factory
- @skobkin__point_tools.service_factory.tag_factory
- @app.point.user_factory
- @app.point.file_factory
- @app.point.comment_factory
- @app.point.tag_factory
# Telegram accounts factory
point_tools.factory.telegram_account:
app.telegram.telegram_account_factory:
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Telegram\AccountFactory
arguments: [@doctrine.orm.entity_manager]
# Custom Markdown parser
markdown.parser.point:
app.point.markdown_parser:
class: Skobkin\Bundle\PointToolsBundle\Service\Markdown\PointParser
arguments: [[], @router]
tags:
@ -85,70 +87,70 @@ services:
# Event listener
point_tools.event_listener.users_updated:
app.event_listener.users_updated:
class: Skobkin\Bundle\PointToolsBundle\EventListener\UsersUpdatedSubscriber
arguments: [@event_dispatcher]
tags:
- { name: doctrine.event_subscriber, connection: default }
point_tools.event_listener.users_renamed_notifier:
app.event_listener.users_renamed_notifier:
class: Skobkin\Bundle\PointToolsBundle\EventListener\UsersRenamedListener
arguments: [@point_tools.telegram.notifier]
arguments: [@app.telegram.notifier]
tags:
- { name: kernel.event_listener, event: app.users.renamed }
point_tools.event_listener.user_subscribers_updated:
app.event_listener.user_subscribers_updated:
class: Skobkin\Bundle\PointToolsBundle\EventListener\UserSubscribersUpdatedListener
arguments: [@point_tools.telegram.notifier]
arguments: [@app.telegram.notifier]
tags:
- { name: kernel.event_listener, event: app.user.subscribers_updated }
# Twig extensions
point_tools.twig.point_avatar_extension:
app.twig.point_users_extension:
class: Skobkin\Bundle\PointToolsBundle\Twig\PointUserExtension
public: false
arguments: ['@skobkin_point_tools.api_user']
arguments: ['@app.point.api_user']
tags:
- { name: twig.extension }
# Telegram services
# API client
point_tools.telegram.api_client:
app.telegram.api_client:
class: unreal4u\TelegramAPI\TgLog
arguments: [%telegram_token%, @logger, @point_tools.http.telegram_client]
arguments: [%telegram_token%, @logger, @app.http.telegram_client]
# Message sender
point_tools.telegram.message_sender:
app.telegram.message_sender:
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\MessageSender
arguments: [@point_tools.telegram.api_client, @twig]
arguments: [@app.telegram.api_client, @twig]
# User notifier
point_tools.telegram.notifier:
app.telegram.notifier:
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\Notifier
arguments: [@doctrine.orm.entity_manager, @point_tools.telegram.message_sender]
arguments: [@doctrine.orm.entity_manager, @app.telegram.message_sender]
# Common incoming message processor
point_tools.telegram.update_dispatcher:
app.telegram.update_dispatcher:
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\IncomingUpdateDispatcher
arguments:
- @point_tools.telegram.private_message_processor
- @point_tools.telegram.inline_query_processor
- @app.telegram.private_message_processor
- @app.telegram.inline_query_processor
# InlineQuery processor
point_tools.telegram.inline_query_processor:
app.telegram.inline_query_processor:
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\InlineQueryProcessor
lazy: true
arguments: [@doctrine.orm.entity_manager, @point_tools.telegram.api_client]
arguments: [@doctrine.orm.entity_manager, @app.telegram.api_client]
# Private message processor
point_tools.telegram.private_message_processor:
app.telegram.private_message_processor:
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\PrivateMessageProcessor
lazy: true
arguments:
- @point_tools.telegram.message_sender
- @skobkin_point_tools.api_user
- @point_tools.factory.telegram_account
- @app.telegram.message_sender
- @app.point.api_user
- @app.telegram.telegram_account_factory
- @doctrine.orm.entity_manager
- %point_id%

View file

@ -19,7 +19,7 @@
</div>
<div class="row comment-text">
<div class="col-xs-12">
{{ comment.text|markdown('markdown.parser.point') }}
{{ comment.text|markdown('app.point.markdown_parser') }}
</div>
</div>
<div class="row comment-footer">

View file

@ -30,7 +30,7 @@
</div>
<div class="row post-text">
<div class="col-xs-12">
{{ post.text|markdown('markdown.parser.point') }}
{{ post.text|markdown('app.point.markdown_parser') }}
</div>
</div>
<div class="row post-files">

View file

@ -2,28 +2,19 @@
namespace Skobkin\Bundle\PointToolsBundle\Service;
use Guzzle\Service\Client;
use Guzzle\Http\Message\Request as GuzzleRequest;
use Guzzle\Http\Message\Response as GuzzleResponse;
use GuzzleHttp\ClientInterface;
use Psr\Http\Message\ResponseInterface;
/**
* @todo Refactor to Guzzle and DTO
* @see https://github.com/misd-service-development/guzzle-bundle/blob/master/Resources/doc/serialization.md
* @see https://github.com/misd-service-development/guzzle-bundle/blob/master/Resources/doc/clients.md
* @see https://github.com/misd-service-development/guzzle-bundle/blob/master/Resources/doc/param_converter.md
* @todo Refactor DTO deserialization
*/
class AbstractApi
{
/**
* @var Client HTTP-client from Guzzle
* @var ClientInterface HTTP-client from Guzzle
*/
protected $client;
/**
* @var bool Use HTTPS instead of HTTP
*/
protected $useHttps;
/**
* @var string Authentication token for API
*/
@ -34,61 +25,32 @@ class AbstractApi
*/
protected $csRfToken;
/**
* @param Client $httpClient HTTP-client from Guzzle
* @param bool $https Use HTTPS instead of HTTP
* @param string $baseUrl Base URL for API
*/
public function __construct(Client $httpClient, $https = true, $baseUrl = null)
public function __construct(ClientInterface $httpClient)
{
$this->client = $httpClient;
$this->useHttps = ($https) ? true : false;
if (null !== $baseUrl) {
$this->setBaseUrl($baseUrl);
}
}
/**
* Make GET request and return Response object
*
* @param string $path Request path
* @param array $parameters Key => Value array of query parameters
* @return GuzzleResponse
*
* @return ResponseInterface
*/
public function sendGetRequest($path, array $parameters = [])
public function sendGetRequest(string $path, array $parameters = []): ResponseInterface
{
/** @var GuzzleRequest $request */
$request = $this->client->get($path);
$query = $request->getQuery();
foreach ($parameters as $parameter => $value) {
$query->set($parameter, $value);
}
return $request->send();
return $this->client->request('GET', $path, ['query' => $parameters]);
}
/**
* Make POST request and return Response object
*
* @param string $path Request path
* @param array $parameters Key => Value array of request data
* @return GuzzleResponse
*
* @return ResponseInterface
*/
public function sendPostRequest($path, array $parameters = [])
public function sendPostRequest(string $path, array $parameters = []): ResponseInterface
{
// Cleaning POST parameters from potential @file injections
// @todo move to new Guzzle
array_walk($parameters, function (string &$value, string $key) {
$value = str_replace('@', '', $value);
});
/** @var GuzzleRequest $request */
$request = $this->client->post($path, null, $parameters);
return $request->send();
return $request = $this->client->request('POST', $path, ['form_params' => $parameters]);
}
/**
@ -98,21 +60,14 @@ class AbstractApi
* @param array $parameters Parameters array used to fill path template
* @param bool $decodeJsonResponse Decode JSON or return plaintext
* @param bool $decodeJsonToObjects Decode JSON objects to PHP objects instead of arrays
*
* @return mixed
*/
public function getGetRequestData($path, array $parameters = [], $decodeJsonResponse = false, $decodeJsonToObjects = false)
public function getGetRequestData($path, array $parameters = [], bool $decodeJsonResponse = false, bool $decodeJsonToObjects = false)
{
$response = $this->sendGetRequest($path, $parameters);
if ($decodeJsonResponse) {
if ($decodeJsonToObjects) {
return json_decode($response->getBody(true));
} else {
return $response->json();
}
} else {
return $response->getBody(true);
}
return $this->processResponse($response, $decodeJsonResponse, $decodeJsonToObjects);
}
/**
@ -120,23 +75,16 @@ class AbstractApi
*
* @param string $path Path template
* @param array $parameters Parameters array used to fill path template
* @param bool $decodeJsonResponse Decode JSON or return plaintext
* @param bool $decodeJsonToObjects Decode JSON objects to PHP objects instead of arrays
* @param bool $decodeJson Decode JSON or return plaintext
* @param bool $decodeToObjects Decode JSON objects to PHP objects instead of arrays
*
* @return mixed
*/
public function getPostRequestData($path, array $parameters = [], $decodeJsonResponse = false, $decodeJsonToObjects = false)
public function getPostRequestData($path, array $parameters = [], bool $decodeJson = false, bool $decodeToObjects = false)
{
$response = $this->sendPostRequest($path, $parameters);
if ($decodeJsonResponse) {
if ($decodeJsonToObjects) {
return json_decode($response->getBody(true));
} else {
return $response->json();
}
} else {
return $response->getBody(true);
}
return $this->processResponse($response, $decodeJson, $decodeToObjects);
}
/**
@ -146,65 +94,26 @@ class AbstractApi
*/
public function getBaseUrl(): string
{
return (string) $this->client->getBaseUrl();
return (string) $this->client->getConfig('base_uri');
}
/**
* Set HTTP client base URL
* @param ResponseInterface $response
* @param bool $decodeJson
* @param bool $decodeToObjects
*
* @param string $baseUrl Base URL of API
* @param bool $useProtocol Do not change URL scheme (http/https) defined in $baseUrl
* @return $this
* @return string|array|object
*/
public function setBaseUrl(string $baseUrl, bool $useProtocol = false): self
private function processResponse(ResponseInterface $response, bool $decodeJson = false, bool $decodeToObjects = false)
{
// Overriding protocol
if (!$useProtocol) {
$baseUrl = str_replace(['http://', 'https://',], ($this->useHttps) ? 'https://' : 'http://', $baseUrl);
if ($decodeJson) {
if ($decodeToObjects) {
return json_decode($response->getBody());
} else {
return json_decode($response->getBody(), true);
}
} else {
return $response->getBody();
}
// Adding missing protocol
if ((false === strpos(strtolower($baseUrl), 'http://')) && (false === strpos(strtolower($baseUrl), 'https://'))) {
$baseUrl = (($this->useHttps) ? 'https://' : 'http://') . $baseUrl;
}
$this->client->setBaseUrl($baseUrl);
return $this;
}
/**
* Check if API service uses HTTPS
*
* @return bool
*/
public function isHttps(): bool
{
return $this->useHttps;
}
/**
* Enable HTTPS
*
* @return $this
*/
public function enableHttps(): self
{
$this->useHttps = true;
$this->setBaseUrl($this->getBaseUrl());
return $this;
}
/**
* Disable HTTPS
*
* @return $this
*/
public function disableHttps(): self
{
$this->useHttps = false;
$this->setBaseUrl($this->getBaseUrl());
return $this;
}
}

View file

@ -9,7 +9,6 @@ use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\ApiException;
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
use Skobkin\Bundle\PointToolsBundle\Service\Factory\UserFactory;
class CommentFactory
{
/**
@ -48,10 +47,11 @@ class CommentFactory
* @param array $data
*
* @return Comment
*
* @throws ApiException
* @throws InvalidResponseException
*/
public function createFromArray(array $data)
public function createFromArray(array $data): Comment
{
$this->validateData($data);
@ -78,9 +78,10 @@ class CommentFactory
* @param array $data
*
* @return Comment[]
*
* @throws ApiException
*/
public function createFromListArray(array $data)
public function createFromListArray(array $data): array
{
$comments = [];

View file

@ -2,17 +2,16 @@
namespace Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Psr\Log\LoggerInterface;
use Skobkin\Bundle\PointToolsBundle\Entity\Blogs\File;
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
class FileFactory
{
/**
* @var EntityManager
* @var EntityManagerInterface
*/
private $em;
@ -26,10 +25,8 @@ class FileFactory
*/
private $fileRepository;
/**
* @param EntityManager $em
*/
public function __construct(LoggerInterface $log, EntityManager $em)
public function __construct(LoggerInterface $log, EntityManagerInterface $em)
{
$this->log = $log;
$this->em = $em;
@ -41,7 +38,7 @@ class FileFactory
*
* @return File[]
*/
public function createFromUrlsArray(array $urlStrings)
public function createFromUrlsArray(array $urlStrings): array
{
$files = [];
@ -59,12 +56,13 @@ class FileFactory
}
/**
* @param $url
* @param string $url
*
* @return File
*
* @throws InvalidResponseException
*/
public function createFromUrl($url)
public function createFromUrl(string $url): File
{
$this->validateData($url);

View file

@ -2,7 +2,7 @@
namespace Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Psr\Log\LoggerInterface;
use Skobkin\Bundle\PointToolsBundle\DTO\Api\Crawler\MetaPost;
@ -14,7 +14,6 @@ use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\Factory\Blogs\InvalidPost
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
use Skobkin\Bundle\PointToolsBundle\Service\Factory\UserFactory;
class PostFactory
{
/**
@ -23,7 +22,7 @@ class PostFactory
private $log;
/**
* @var EntityManager
* @var EntityManagerInterface
*/
private $em;
@ -52,10 +51,8 @@ class PostFactory
*/
private $tagFactory;
/**
* @param EntityManager $em
*/
public function __construct(LoggerInterface $log, EntityManager $em, UserFactory $userFactory, FileFactory $fileFactory, CommentFactory $commentFactory, TagFactory $tagFactory)
public function __construct(LoggerInterface $log, EntityManagerInterface $em, UserFactory $userFactory, FileFactory $fileFactory, CommentFactory $commentFactory, TagFactory $tagFactory)
{
$this->log = $log;
$this->userFactory = $userFactory;
@ -76,7 +73,7 @@ class PostFactory
* @throws ApiException
* @throws InvalidResponseException
*/
public function createFromPageDTO(PostsPage $page)
public function createFromPageDTO(PostsPage $page): bool
{
$posts = [];
@ -116,18 +113,20 @@ class PostFactory
* @param MetaPost $postData
*
* @return Post
*
* @throws ApiException
* @throws InvalidPostDataException
*/
private function createFromDTO(MetaPost $postData)
private function createFromDTO(MetaPost $postData): Post
{
if (!$this->validateMetaPost($postData)) {
// FIXME
throw new InvalidPostDataException('Invalid post data', $postData);
}
if (!$postData->getPost()->getAuthor()->getId()) {
$this->log->error('Post author does not contain id', ['post_id' => $postData->getPost()->getId()]);
throw new InvalidPostDataException('Post author does not contain id', $postData);
throw new InvalidPostDataException('Post author does not contain id', $postData->getPost());
}
try {

View file

@ -2,17 +2,16 @@
namespace Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Psr\Log\LoggerInterface;
use Skobkin\Bundle\PointToolsBundle\Entity\Blogs\Tag;
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
class TagFactory
{
/**
* @var EntityManager
* @var EntityManagerInterface
*/
private $em;
@ -26,10 +25,8 @@ class TagFactory
*/
private $tagRepository;
/**
* @param EntityManager $em
*/
public function __construct(LoggerInterface $log, EntityManager $em)
public function __construct(LoggerInterface $log, EntityManagerInterface $em)
{
$this->log = $log;
$this->em = $em;
@ -41,7 +38,7 @@ class TagFactory
*
* @return Tag[]
*/
public function createFromStringsArray(array $tagStrings)
public function createFromStringsArray(array $tagStrings): array
{
$tags = [];
@ -58,16 +55,8 @@ class TagFactory
return $tags;
}
/**
* @param $text
*
* @return Tag
* @throws InvalidResponseException
*/
public function createFromString($text)
public function createFromString(string $text): Tag
{
$this->validateData($text);
if (null === ($tag = $this->tagRepository->findOneByLowerText($text))) {
// Creating new tag
$tag = new Tag($text);
@ -76,17 +65,4 @@ class TagFactory
return $tag;
}
/**
* @param $data
*
* @throws InvalidResponseException
*/
private function validateData($data)
{
if (!is_string($data)) {
// @todo Change exception
throw new InvalidResponseException('Tag data must be a string');
}
}
}

View file

@ -2,7 +2,6 @@
namespace Skobkin\Bundle\PointToolsBundle\Service\Factory;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Skobkin\Bundle\PointToolsBundle\DTO\Api\Crawler\User as UserDTO;
@ -15,7 +14,7 @@ use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
class UserFactory
{
/**
* @var EntityManager
* @var EntityManagerInterface
*/
private $em;
@ -25,9 +24,9 @@ class UserFactory
private $userRepository;
/**
* @param EntityManager $em
* @param EntityManagerInterface $em
*/
public function __construct(EntityManager $em)
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->userRepository = $em->getRepository('SkobkinPointToolsBundle:User');
@ -37,10 +36,11 @@ class UserFactory
* @param array $data
*
* @return User
*
* @throws ApiException
* @throws InvalidResponseException
*/
public function createFromArray(array $data)
public function createFromArray(array $data): User
{
$this->validateArrayData($data);
@ -64,10 +64,11 @@ class UserFactory
* @param UserDTO $userData
*
* @return User
*
* @throws ApiException
* @throws InvalidUserDataException
*/
public function createFromDTO(UserDTO $userData)
public function createFromDTO(UserDTO $userData): User
{
$this->validateDTOData($userData);
@ -100,7 +101,7 @@ class UserFactory
}
/**
* @param array $data
* @param UserDTO $data
*
* @throws InvalidResponseException
*/

View file

@ -2,7 +2,7 @@
namespace Skobkin\Bundle\PointToolsBundle\Service;
use Guzzle\Service\Client;
use GuzzleHttp\ClientInterface;
use Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\PostFactory;
/**
@ -16,9 +16,9 @@ class PostApi extends AbstractApi
private $postFactory;
public function __construct(Client $httpClient, $https = true, $baseUrl = null, PostFactory $postFactory)
public function __construct(ClientInterface $httpClient, PostFactory $postFactory)
{
parent::__construct($httpClient, $https, $baseUrl);
parent::__construct($httpClient);
$this->postFactory = $postFactory;
}

View file

@ -4,8 +4,8 @@ namespace Skobkin\Bundle\PointToolsBundle\Service;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Guzzle\Http\Exception\ClientErrorResponseException;
use Guzzle\Service\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use JMS\Serializer\Serializer;
use Skobkin\Bundle\PointToolsBundle\DTO\Api\Auth;
use Skobkin\Bundle\PointToolsBundle\Entity\User;
@ -44,9 +44,9 @@ class UserApi extends AbstractApi
private $serializer;
public function __construct(Client $httpClient, $https = true, $baseUrl = null, EntityManager $entityManager, Serializer $serializer)
public function __construct(ClientInterface $httpClient, EntityManager $entityManager, Serializer $serializer)
{
parent::__construct($httpClient, $https, $baseUrl);
parent::__construct($httpClient);
$this->em = $entityManager;
$this->serializer = $serializer;
@ -78,7 +78,7 @@ class UserApi extends AbstractApi
);
return $this->serializer->deserialize($authData, Auth::class, 'json');
} catch (ClientErrorResponseException $e) {
} catch (RequestException $e) {
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
throw new InvalidResponseException('API method not found', 0, $e);
} else {
@ -93,7 +93,7 @@ class UserApi extends AbstractApi
$this->getPostRequestData('/api/logout', ['csrf_token' => $auth->getCsRfToken()]);
return true;
} catch (ClientErrorResponseException $e) {
} 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()) {
@ -108,16 +108,18 @@ class UserApi extends AbstractApi
* Get user subscribers by user login
*
* @param string $login
*
* @return User[]
*
* @throws ApiException
* @throws InvalidResponseException
* @throws UserNotFoundException
*/
public function getUserSubscribersByLogin($login)
public function getUserSubscribersByLogin(string $login): array
{
try {
$usersList = $this->getGetRequestData('/api/user/'.urlencode($login).'/subscribers', [], true);
} catch (ClientErrorResponseException $e) {
} catch (RequestException $e) {
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
throw new UserNotFoundException('User not found', 0, $e, null, $login);
} else {
@ -131,21 +133,19 @@ class UserApi extends AbstractApi
/**
* Get user subscribers by user id
*
* @param $id
* @param int $id
*
* @return User[]
*
* @throws ApiException
* @throws InvalidResponseException
* @throws UserNotFoundException
*/
public function getUserSubscribersById($id)
public function getUserSubscribersById(int $id): array
{
if (!is_numeric($id)) {
throw new \InvalidArgumentException('$id must be an integer');
}
try {
$usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscribers', [], true);
} catch (ClientErrorResponseException $e) {
} catch (RequestException $e) {
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
throw new UserNotFoundException('User not found', 0, $e, $id);
} else {
@ -160,16 +160,18 @@ class UserApi extends AbstractApi
* Get user subscriptions by user login
*
* @param string $login
*
* @return User[]
*
* @throws ApiException
* @throws InvalidResponseException
* @throws UserNotFoundException
*/
public function getUserSubscriptionsByLogin($login)
public function getUserSubscriptionsByLogin(string $login): array
{
try {
$usersList = $this->getGetRequestData('/api/user/'.urlencode($login).'/subscriptions', [], true);
} catch (ClientErrorResponseException $e) {
} catch (RequestException $e) {
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
throw new UserNotFoundException('User not found', 0, $e, null, $login);
} else {
@ -183,21 +185,19 @@ class UserApi extends AbstractApi
/**
* Get user subscriptions by user id
*
* @param $id
* @param int $id
*
* @return User[]
*
* @throws ApiException
* @throws InvalidResponseException
* @throws UserNotFoundException
*/
public function getUserSubscriptionsById($id)
public function getUserSubscriptionsById(int $id): array
{
if (!is_numeric($id)) {
throw new \InvalidArgumentException('$id must be an integer');
}
try {
$usersList = $this->getGetRequestData('/api/user/id/'.(int) $id.'/subscriptions', [], true);
} catch (ClientErrorResponseException $e) {
} catch (RequestException $e) {
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
throw new UserNotFoundException('User not found', 0, $e, $id);
} else {
@ -212,15 +212,17 @@ class UserApi extends AbstractApi
* Get single user by login
*
* @param string $login
*
* @return User
*
* @throws UserNotFoundException
* @throws ClientErrorResponseException
* @throws RequestException
*/
public function getUserByLogin($login)
public function getUserByLogin(string $login): User
{
try {
$userInfo = $this->getGetRequestData('/api/user/login/'.urlencode($login), [], true);
} catch (ClientErrorResponseException $e) {
} catch (RequestException $e) {
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
throw new UserNotFoundException('User not found', 0, $e, null, $login);
} else {
@ -234,20 +236,18 @@ class UserApi extends AbstractApi
/**
* Get single user by id
*
* @param $id
* @param int $id
*
* @return User
*
* @throws UserNotFoundException
* @throws ClientErrorResponseException
* @throws RequestException
*/
public function getUserById($id)
public function getUserById(int $id): User
{
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) {
$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 {
@ -262,16 +262,14 @@ class UserApi extends AbstractApi
* 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)
public function getUserFromUserInfo(array $userInfo): User
{
if (!is_array($userInfo)) {
throw new \InvalidArgumentException('$userInfo must be an array');
}
// @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 */
@ -297,16 +295,14 @@ class UserApi extends AbstractApi
* 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 = [])
private function getUsersFromList(array $users = []): array
{
if (!is_array($users)) {
throw new \InvalidArgumentException('$users must be an array');
}
/** @var User[] $resultUsers */
$resultUsers = [];
@ -338,10 +334,11 @@ class UserApi extends AbstractApi
* Creates URL of avatar with specified size by User object
*
* @param User $user
* @param int $size
* @param string $size
*
* @return string
*/
public function getAvatarUrl(User $user, $size)
public function getAvatarUrl(User $user, string $size): string
{
return $this->getAvatarUrlByLogin($user->getLogin(), $size);
}
@ -349,12 +346,12 @@ class UserApi extends AbstractApi
/**
* Creates URL of avatar with specified size by login string
*
* @param $login
* @param $size
* @param string $login
* @param string $size
*
* @return string
*/
public function getAvatarUrlByLogin($login, $size)
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.');

View file

@ -10,9 +10,9 @@ umask(0002);
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
//|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !(
in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) ||
//in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) ||
php_sapi_name() === 'cli-server'
)
) {