Completed
Push — master ( b123ad...2604a0 )
by Joachim
02:07
created

ConsumeWebhookQueueCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Loevgaard\DandomainAltapayBundle\Command;
4
5
use Doctrine\Common\Collections\Criteria;
6
use GuzzleHttp\Client;
7
use GuzzleHttp\Exception\TransferException;
8
use GuzzleHttp\Psr7\Request;
9
use GuzzleHttp\RequestOptions;
10
use JMS\Serializer\SerializerInterface;
11
use Loevgaard\DandomainAltapayBundle\Entity\WebhookExchange;
12
use Loevgaard\DandomainAltapayBundle\Entity\WebhookExchangeRepository;
13
use Loevgaard\DandomainAltapayBundle\Entity\WebhookQueueItem;
14
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
15
use Symfony\Component\Console\Command\LockableTrait;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
class ConsumeWebhookQueueCommand extends ContainerAwareCommand
20
{
21
    use LockableTrait;
22
23
    /**
24
     * @var OutputInterface
25
     */
26
    private $output;
27
28
    /**
29
     * @var WebhookExchangeRepository
30
     */
31
    private $webhookExchangeRepository;
32
33
    /**
34
     * @var SerializerInterface
35
     */
36
    private $serializer;
37
38
    /**
39
     * @var Client
40
     */
41
    private $httpClient;
42
43
    public function __construct(
44
        WebhookExchangeRepository $webhookExchangeRepository,
45
        SerializerInterface $serializer
46
    ) {
47
        $this->webhookExchangeRepository = $webhookExchangeRepository;
48
        $this->serializer = $serializer;
49
50
        parent::__construct();
51
    }
52
53
    protected function configure()
54
    {
55
        $this->setName('loevgaard:dandomain:altapay:call-webhooks')
56
            ->setDescription('Will call all the respective webhook URLs')
57
        ;
58
    }
59
60
    protected function execute(InputInterface $input, OutputInterface $output)
61
    {
62
        if (!($this->lock())) {
63
            $output->writeln('The command is already running in another process.');
64
65
            return 0;
66
        }
67
68
        $this->output = $output;
69
70
        /** @var WebhookExchange[] $webhookExchanges */
71
        $webhookExchanges = $this->webhookExchangeRepository->findAll();
72
73
        foreach ($webhookExchanges as $webhookExchange) {
74
            $now = new \DateTimeImmutable();
75
76
            $criteria = Criteria::create()
77
                ->where(
78
                    Criteria::expr()->orX(
79
                        Criteria::expr()->eq('status', WebhookQueueItem::STATUS_PENDING),
80
                        Criteria::expr()->eq('status', WebhookQueueItem::STATUS_ERROR)
81
                    )
82
                )->andWhere(Criteria::expr()->lte('nextTry', $now))
83
                ->setMaxResults(50)
84
            ;
85
86
            /** @var WebhookQueueItem[] $webhookQueueItems */
87
            $webhookQueueItems = $webhookExchange->getWebhookQueueItems()->matching($criteria);
88
89
            foreach ($webhookQueueItems as $webhookQueueItem) {
90
                try {
91
                    if ($this->doRequest($webhookQueueItem)) {
92
                        $webhookQueueItem->markAsSuccess();
93
                    }
94
                } catch (\Exception $e) {
95
                    $webhookQueueItem->markAsError($e->getMessage());
96
                }
97
98
                $this->webhookExchangeRepository->flush();
99
            }
100
        }
101
102
        return 0;
103
    }
104
105
    /**
106
     * @param WebhookQueueItem $webhookQueueItem
107
     *
108
     * @return bool
109
     */
110
    private function doRequest(WebhookQueueItem $webhookQueueItem): bool
111
    {
112
        if (!$this->httpClient) {
113
            $this->httpClient = new Client([
114
                RequestOptions::ALLOW_REDIRECTS => false,
115
                RequestOptions::CONNECT_TIMEOUT => 15,
116
                RequestOptions::TIMEOUT => 30,
117
                RequestOptions::HTTP_ERRORS => false,
118
                RequestOptions::HEADERS => [
119
                    'Content-Type' => 'application/json',
120
                ],
121
            ]);
122
        }
123
124
        $request = new Request('post', $webhookQueueItem->getWebhookExchange()->getUrl(), [], $webhookQueueItem->getContent());
125
        $webhookQueueItem->setRequest($request);
0 ignored issues
show
Documentation introduced by
$request is of type object<GuzzleHttp\Psr7\Request>, but the function expects a null|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
126
127
        try {
128
            $response = $this->httpClient->send($request);
129
            $webhookQueueItem->setResponse($response);
130
        } catch (TransferException $e) {
131
            $this->output->writeln('[Webhook Queue Item: '.$webhookQueueItem->getId().'] Webhook URL ('.$webhookQueueItem->getWebhookExchange()->getUrl().') returned an error: '.$e->getMessage(), OutputInterface::VERBOSITY_VERBOSE);
132
            $webhookQueueItem->markAsError($e->getMessage());
133
134
            return false;
135
        }
136
137
        if (200 !== $response->getStatusCode()) {
138
            $this->output->writeln('[Webhook Queue Item: '.$webhookQueueItem->getId().'] Webhook URL ('.$webhookQueueItem->getWebhookExchange()->getUrl().') returned status code: '.$response->getStatusCode(), OutputInterface::VERBOSITY_VERBOSE);
139
            $webhookQueueItem->markAsError('Status code was '.$response->getStatusCode());
140
141
            return false;
142
        }
143
144
        return true;
145
    }
146
}
147