Workflow::isLocked()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Yep\WorkflowLogger;
4
5
use Psr\Log\LoggerInterface as PsrLoggerInterface;
6
use Yep\WorkflowLogger\Exception\LevelIsNotDefinedException;
7
use Yep\WorkflowLogger\Exception\WorkflowIsLockedException;
8
use Yep\WorkflowLogger\Formatter\FormatterInterface;
9
10
/**
11
 * Class Workflow
12
 *
13
 * @package Yep\WorkflowLogger
14
 * @author  Martin Zeman (Zemistr) <[email protected]>
15
 */
16
class Workflow implements PsrLoggerInterface
17
{
18
    const EMERGENCY = 'emergency';
19
    const ALERT = 'alert';
20
    const CRITICAL = 'critical';
21
    const ERROR = 'error';
22
    const WARNING = 'warning';
23
    const NOTICE = 'notice';
24
    const INFO = 'info';
25
    const DEBUG = 'debug';
26
27
    /**
28
     * Logging levels from syslog protocol defined in RFC 5424
29
     *
30
     * @var array|string[] $levels Logging levels
31
     */
32
    protected static $levels = [
33
      self::DEBUG => 'DEBUG',
34
      self::INFO => 'INFO',
35
      self::NOTICE => 'NOTICE',
36
      self::WARNING => 'WARNING',
37
      self::ERROR => 'ERROR',
38
      self::CRITICAL => 'CRITICAL',
39
      self::ALERT => 'ALERT',
40
      self::EMERGENCY => 'EMERGENCY',
41
    ];
42
43
    /**
44
     * @var int|string
45
     */
46
    protected $level;
47
48
    /**
49
     * @var FormatterInterface
50
     */
51
    protected $formatter;
52
53
    /**
54
     * @var PsrLoggerInterface
55
     */
56
    protected $logger;
57
58
    /**
59
     * @var array|Record[]
60
     */
61
    protected $records = [];
62
63
    /**
64
     * @var \DateTimeZone
65
     */
66
    protected $timezone;
67
68
    /**
69
     * @var bool
70
     */
71
    protected $locked = false;
72
73
    /**
74
     * Workflow constructor.
75
     *
76
     * @param PsrLoggerInterface $logger    Main logger
77
     * @param FormatterInterface $formatter Workflow records formatter
78
     * @param \DateTimeZone      $timezone  Current timezone
79
     * @param int|string         $level     Workflow level code
80
     */
81 9
    public function __construct(
82
      PsrLoggerInterface $logger,
83
      FormatterInterface $formatter,
84
      \DateTimeZone $timezone,
85
      $level
86
    ) {
87 9
        $this->logger = $logger;
88 9
        $this->formatter = $formatter;
89 9
        $this->timezone = $timezone;
90 9
        $this->level = $level;
91 9
    }
92
93
    /**
94
     * @return \DateTime
95
     */
96 3
    protected function getCurrentDateTime()
97
    {
98
        // php7.1+ always has microseconds enabled, so we do not need this hack
99 3
        if (PHP_VERSION_ID < 70100) {
100
            $microtime = sprintf('%.6F', microtime(true));
101
            $time = \DateTime::createFromFormat(
102
              'U.u',
103
              $microtime,
104
              $this->timezone
105
            );
106
        }
107
        else {
108 3
            $time = new \DateTime(null, $this->timezone);
109
        }
110
111 3
        $time->setTimezone($this->timezone);
112
113 3
        return $time;
114
    }
115
116
    /**
117
     * @return int|string
118
     */
119 2
    public function getLevel()
120
    {
121 2
        return $this->level;
122
    }
123
124
    /**
125
     * Gets the name of the logging level.
126
     *
127
     * @param string $level
128
     * @return string
129
     * @throws LevelIsNotDefinedException
130
     */
131 3
    public function getLevelName($level)
132
    {
133 3
        if (!isset(static::$levels[$level])) {
134 2
            throw LevelIsNotDefinedException::create($level, static::$levels);
135
        }
136
137 2
        return static::$levels[$level];
138
    }
139
140
    /**
141
     * @return bool
142
     */
143 6
    public function isLocked()
144
    {
145 6
        return $this->locked;
146
    }
147
148
    /**
149
     * @return void
150
     */
151 5
    public function lock()
152
    {
153 5
        $this->locked = true;
154 5
    }
155
156
    /**
157
     * Logs with a workflow level and with all workflow records
158
     *
159
     * @param  string $message The log message
160
     * @param  array  $context The log context
161
     * @return void
162
     * @throws WorkflowIsLockedException
163
     */
164 2
    public function finish($message = '', array $context = [])
165
    {
166 2
        if ($this->isLocked()) {
167 1
            throw WorkflowIsLockedException::create();
168
        }
169
170 1
        $this->lock();
171 1
        $message .= $message === '' ? '' : "\n\n";
172 1
        $message .= "Workflow:\n";
173
174 1
        foreach ($this->records as $record) {
175 1
            $message .= $this->formatter->format($record);
176
        }
177
178 1
        $this->logger->log($this->level, $message, $context);
179 1
    }
180
181
    /**
182
     * Logs workflow record with an arbitrary level.
183
     *
184
     * @param  string $level   The logging level
185
     * @param  string $message The log message
186
     * @param  array  $context The log context
187
     * @return void
188
     * @throws LevelIsNotDefinedException
189
     * @throws WorkflowIsLockedException
190
     */
191 3
    public function log($level, $message, array $context = [])
192
    {
193 3
        if ($this->isLocked()) {
194 1
            throw WorkflowIsLockedException::create();
195
        }
196
197 2
        $this->records[] = new Record(
198 2
          $this->getCurrentDateTime(),
199 2
          $message,
200 2
          $this->getLevelName($level),
201 1
          $context
202
        );
203 1
    }
204
205
    /**
206
     * System is unusable.
207
     *
208
     * @param  string $message The log message
209
     * @param  array  $context The log context
210
     * @return void
211
     * @throws WorkflowIsLockedException
212
     * @throws LevelIsNotDefinedException
213
     */
214 1
    public function emergency($message, array $context = [])
215
    {
216 1
        $this->log(static::EMERGENCY, $message, $context);
217 1
    }
218
219
    /**
220
     * Action must be taken immediately.
221
     *
222
     * Example: Entire website down, database unavailable, etc. This should
223
     * trigger the SMS alerts and wake you up.
224
     *
225
     * @param  string $message The log message
226
     * @param  array  $context The log context
227
     * @return void
228
     * @throws WorkflowIsLockedException
229
     * @throws LevelIsNotDefinedException
230
     */
231 1
    public function alert($message, array $context = [])
232
    {
233 1
        $this->log(static::ALERT, $message, $context);
234 1
    }
235
236
    /**
237
     * Critical conditions.
238
     *
239
     * Example: Application component unavailable, unexpected exception.
240
     *
241
     * @param  string $message The log message
242
     * @param  array  $context The log context
243
     * @return void
244
     * @throws WorkflowIsLockedException
245
     * @throws LevelIsNotDefinedException
246
     */
247 1
    public function critical($message, array $context = [])
248
    {
249 1
        $this->log(static::CRITICAL, $message, $context);
250 1
    }
251
252
    /**
253
     * Runtime errors that do not require immediate action but should typically
254
     * be logged and monitored.
255
     *
256
     * @param  string $message The log message
257
     * @param  array  $context The log context
258
     * @return void
259
     * @throws WorkflowIsLockedException
260
     * @throws LevelIsNotDefinedException
261
     */
262 1
    public function error($message, array $context = [])
263
    {
264 1
        $this->log(static::ERROR, $message, $context);
265 1
    }
266
267
    /**
268
     * Exceptional occurrences that are not errors.
269
     *
270
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
271
     * that are not necessarily wrong.
272
     *
273
     * @param  string $message The log message
274
     * @param  array  $context The log context
275
     * @return void
276
     * @throws WorkflowIsLockedException
277
     * @throws LevelIsNotDefinedException
278
     */
279 1
    public function warning($message, array $context = [])
280
    {
281 1
        $this->log(static::WARNING, $message, $context);
282 1
    }
283
284
    /**
285
     * Normal but significant events.
286
     *
287
     * @param  string $message The log message
288
     * @param  array  $context The log context
289
     * @return void
290
     * @throws WorkflowIsLockedException
291
     * @throws LevelIsNotDefinedException
292
     */
293 1
    public function notice($message, array $context = [])
294
    {
295 1
        $this->log(static::NOTICE, $message, $context);
296 1
    }
297
298
    /**
299
     * Interesting events.
300
     *
301
     * Example: User logs in, SQL logs.
302
     *
303
     * @param  string $message The log message
304
     * @param  array  $context The log context
305
     * @return void
306
     * @throws WorkflowIsLockedException
307
     * @throws LevelIsNotDefinedException
308
     */
309 1
    public function info($message, array $context = [])
310
    {
311 1
        $this->log(static::INFO, $message, $context);
312 1
    }
313
314
    /**
315
     * Detailed debug information.
316
     *
317
     * @param  string $message The log message
318
     * @param  array  $context The log context
319
     * @return void
320
     * @throws WorkflowIsLockedException
321
     * @throws LevelIsNotDefinedException
322
     */
323 1
    public function debug($message, array $context = [])
324
    {
325 1
        $this->log(static::DEBUG, $message, $context);
326 1
    }
327
}
328