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 ( d93ae1...1b6da2 )
by Cees-Jan
07:54 queued 06:14
created

LogglyLogger::format()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2.0023

Importance

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