GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 6e132b...55046d )
by Cees-Jan
02:27
created

LogglyLogger::processPlaceHolders()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 8.3844

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 9
cts 11
cp 0.8182
rs 7.7777
c 0
b 0
f 0
cc 8
eloc 12
nc 5
nop 2
crap 8.3844
1
<?php declare(strict_types=1);
2
3
namespace WyriHaximus\React\PSR3\Loggly;
4
5
use Psr\Log\AbstractLogger;
6
use Psr\Log\InvalidArgumentException;
7
use Psr\Log\LogLevel;
8
use React\Dns\Resolver\Factory as ResolverFactory;
9
use React\EventLoop\LoopInterface;
10
use React\HttpClient\Client;
11
use React\HttpClient\Factory as HttpClientFactory;
12
13
final class LogglyLogger extends AbstractLogger
14
{
15
    /**
16
     * Logging levels PSR-3 LogLevel enum
17
     *
18
     * @var array $levels Logging levels
19
     */
20
    const LOG_LEVELS = [
21
        LogLevel::DEBUG     => 'DEBUG',
22
        LogLevel::INFO      => 'INFO',
23
        LogLevel::NOTICE    => 'NOTICE',
24
        LogLevel::WARNING   => 'WARNING',
25
        LogLevel::ERROR     => 'ERROR',
26
        LogLevel::CRITICAL  => 'CRITICAL',
27
        LogLevel::ALERT     => 'ALERT',
28
        LogLevel::EMERGENCY => 'EMERGENCY',
29
    ];
30
31
    /**
32
     * @var Client
33
     */
34
    private $httpClient;
35
36
    /**
37
     * @var string
38
     */
39
    private $token;
40
41 2
    public static function create(LoopInterface $loop, string $token): self
42
    {
43 2
        $resolverFactory = new ResolverFactory();
44 2
        $resolver = $resolverFactory->create('8.8.8.8', $loop);
45
46 2
        $factory = new HttpClientFactory();
47 2
        $httpClient = $factory->create($loop, $resolver);
48
49 2
        return new self($httpClient, $token);
50
    }
51
52 12
    public static function createFromHttpClient(Client $httpClient, string $token): self
53
    {
54 12
        return new self($httpClient, $token);
55
    }
56
57 14
    private function __construct(Client $httpClient, string $token)
58
    {
59 14
        $this->httpClient = $httpClient;
60 14
        $this->token = $token;
61 14
    }
62
63 13
    public function log($level, $message, array $context = [])
64
    {
65 13
        $levels = self::LOG_LEVELS;
66 13
        if (!isset($levels[$level])) {
67 1
            throw new InvalidArgumentException(
68 1
                'Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(self::LOG_LEVELS))
69
            );
70
        }
71
72 12
        $data = $this->format($level, $message, $context);
73 12
        $this->send($data);
74 12
    }
75
76 12
    protected function format($level, $message, array $context): string
77
    {
78 12
        $message = (string)$message;
79 12
        $context = $this->normalizeContext($context);
80 12
        $message = $this->processPlaceHolders($message, $context);
81 12
        $json = json_encode([
82 12
            'level'   => $level,
83 12
            'message' => $message,
84 12
            'level_message' => $level . ' ' . $message,
85 12
            'context' => $context,
86
        ]);
87
88 12
        if ($json === false) {
89
            throw new InvalidArgumentException(json_last_error_msg());
90
        }
91
92 12
        return $json;
93
    }
94
95
    /**
96
     * @param string $message
97
     * @param array $context
98
     * @return string
99
     *
100
     * Method copied from: https://github.com/Seldaek/monolog/blob/6e6586257d9fb231bf039563632e626cdef594e5/src/Monolog/Processor/PsrLogMessageProcessor.php
101
     */
102 12
    private function processPlaceHolders(string $message, array $context): string
103
    {
104 12
        if (false === strpos($message, '{')) {
105 3
            return $message;
106
        }
107
108 9
        $replacements = array();
109 9
        foreach ($context as $key => $val) {
110 9
            if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, '__toString'))) {
111 9
                $replacements['{'.$key.'}'] = $val;
112
            } elseif (is_object($val)) {
113
                $replacements['{'.$key.'}'] = '[object '.get_class($val).']';
114
            } else {
115 9
                $replacements['{'.$key.'}'] = '['.gettype($val).']';
116
            }
117
        }
118
119 9
        return strtr($message, $replacements);
120
    }
121
122 12
    private function normalizeContext(array $context): array
123
    {
124 12
        foreach ($context as $index => $value) {
125 11
            if (is_array($value)) {
126 1
                $context[$index] = $this->normalizeContext($value);
127 1
                continue;
128
            }
129
130 11
            if (is_resource($value)) {
131 1
                $context[$index] = sprintf('[resource] (%s)', get_resource_type($value));
132 11
                continue;
133
            }
134
        }
135 12
        return $context;
136
    }
137
138 12
    protected function send(string $data)
139
    {
140 12
        $this->httpClient->request(
141 12
            'POST',
142 12
            'https://logs-01.loggly.com/inputs/' . $this->token,
143
            [
144 12
                'Content-Type' => 'application/json',
145 12
                'Content-Length' => strlen($data),
146
            ],
147 12
            '1.1'
148 12
        )->end($data);
149 12
    }
150
}
151