Passed
Push — master ( 6c42be...776013 )
by Igor
02:03
created

processNotification()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 46
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 46
rs 9.1608
c 0
b 0
f 0
cc 5
nc 8
nop 1
1
<?php
2
/**
3
 * PHP version 5.4 and 7
4
 *
5
 * @package   Payever\Payments
6
 * @author    Hennadii.Shymanskyi <[email protected]>
7
 * @copyright 2017-2019 payever GmbH
8
 * @license   MIT <https://opensource.org/licenses/MIT>
9
 */
10
11
namespace Payever\ExternalIntegration\Payments\Notification;
12
13
use Payever\ExternalIntegration\Core\Lock\LockInterface;
14
use Payever\ExternalIntegration\Payments\Http\RequestEntity\NotificationRequestEntity;
15
use Psr\Log\LoggerInterface;
16
17
/**
18
 * PHP version 5.4 and 7
19
 *
20
 * @package   Payever\Payments
21
 * @author    Hennadii.Shymanskyi <[email protected]>
22
 * @copyright 2017-2019 payever GmbH
23
 * @license   MIT <https://opensource.org/licenses/MIT>
24
 */
25
class NotificationRequestProcessor
26
{
27
    const NOTIFICATION_LOCK_SECONDS = 30;
28
29
    /** @var NotificationHandlerInterface */
30
    protected $handler;
31
32
    /** @var LockInterface */
33
    protected $lock;
34
35
    /** @var LoggerInterface */
36
    protected $logger;
37
38
    /**
39
     * NotificationService constructor.
40
     *
41
     * @param NotificationHandlerInterface $handler
42
     * @param LockInterface $lock
43
     * @param LoggerInterface $logger
44
     */
45
    public function __construct(
46
        NotificationHandlerInterface $handler,
47
        LockInterface $lock,
48
        LoggerInterface $logger
49
    ) {
50
        $this->handler = $handler;
51
        $this->lock = $lock;
52
        $this->logger = $logger;
53
    }
54
55
    /**
56
     * @param string|null $payload
57
     *
58
     * @return NotificationResult
59
     *
60
     * @throws \RuntimeException when couldn't get payload
61
     * @throws \UnexpectedValueException when notification validation failed
62
     */
63
    public function processNotification($payload = null)
64
    {
65
        if (is_null($payload)) {
66
            $payload = $this->getRequestPayload();
67
        }
68
69
        if (!$payload) {
70
            throw new \RuntimeException('Got empty notification payload', 20);
71
        }
72
73
        $logPrefix = '[Notification]';
74
        $notificationResult = new NotificationResult();
75
        $notificationEntity = $this->unserializePayload($payload);
76
77
        if (!$notificationEntity->isValid()) {
78
            throw new \UnexpectedValueException('Notification entity is invalid', 21);
79
        }
80
81
        $paymentId = $notificationEntity->getPayment()->getId();
82
83
        $this->logger->debug(sprintf('%s Attempting to lock %s', $logPrefix, $paymentId));
84
        $this->lock->acquireLock($paymentId, static::NOTIFICATION_LOCK_SECONDS);
85
        $this->logger->debug(sprintf('%s Locked  %s', $logPrefix, $paymentId));
86
87
        try {
88
            $this->handler->handleNotification($notificationEntity, $notificationResult);
89
        } catch (\Exception $exception) {
90
            $this->logger->critical(
91
                sprintf('%s Exception while handling notification: %s', $logPrefix, $exception->getMessage())
92
            );
93
            $notificationResult->addException($exception);
94
        }
95
96
        $this->lock->releaseLock($paymentId);
97
        $this->logger->debug(sprintf('%s Unlocked  %s', $logPrefix, $paymentId));
98
99
        $this->logger->info(
100
            sprintf(
101
                '%s Processed notification for payment %s: %s',
102
                $logPrefix,
103
                $paymentId,
104
                (string) $notificationResult
105
            )
106
        );
107
108
        return $notificationResult;
109
    }
110
111
    /**
112
     * @param string $payload
113
     *
114
     * @return NotificationRequestEntity
115
     */
116
    protected function unserializePayload($payload)
117
    {
118
        return new NotificationRequestEntity(json_decode($payload, true));
119
    }
120
121
    /**
122
     * @return false|string
123
     */
124
    protected function getRequestPayload()
125
    {
126
        return file_get_contents('php://input');
127
    }
128
}
129