Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
File
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
4 / 4
14
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 writeLog
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
1 / 1
10
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Log\Writer;
15
16/**
17 * File log writer class
18 *
19 * @category   Pop
20 * @package    Pop\Log
21 * @author     Nick Sagona, III <dev@nolainteractive.com>
22 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
23 * @license    http://www.popphp.org/license     New BSD License
24 * @version    4.0.0
25 */
26class File extends AbstractWriter
27{
28
29    /**
30     * Log file
31     * @var ?string
32     */
33    protected ?string $file = null;
34
35    /**
36     * Log file type
37     * @var ?string
38     */
39    protected ?string $type = null;
40
41    /**
42     * Constructor
43     *
44     * Instantiate the file writer object
45     *
46     * @param  string $file
47     */
48    public function __construct(string $file)
49    {
50        if (!file_exists($file)) {
51            touch($file);
52        }
53
54        $parts = pathinfo($file);
55
56        $this->file = $file;
57        $this->type = $parts['extension'] ?? null;
58    }
59
60    /**
61     * Get file
62     * @return string
63     */
64    public function getFile(): string
65    {
66        return $this->file;
67    }
68
69    /**
70     * Get type
71     * @return ?string
72     */
73    public function getType(): ?string
74    {
75        return $this->type;
76    }
77
78    /**
79     * Write to the log
80     *
81     * @param  mixed  $level
82     * @param  string $message
83     * @param  array  $context
84     * @return File
85     */
86    public function writeLog(mixed $level, string $message, array $context = []): File
87    {
88        if ($this->isWithinLogLimit($level)) {
89            switch (strtolower($this->type)) {
90                case 'csv':
91                    $message = '"' . str_replace('"', '\"', $message) . '"' ;
92                    $entry   = $context['timestamp'] . "," . $level . "," .
93                        $context['name'] . "," . $message . "," . $this->getContext($context) . PHP_EOL;
94                    file_put_contents($this->file, $entry, FILE_APPEND);
95                    break;
96
97                case 'tsv':
98                    $message = '"' . str_replace('"', '\"', $message) . '"' ;
99                    $entry   = $context['timestamp'] . "\t" . $level . "\t" .
100                        $context['name'] . "\t" . $message . "\t" . $this->getContext($context) . PHP_EOL;
101                    file_put_contents($this->file, $entry, FILE_APPEND);
102                    break;
103
104                case 'xml':
105                    $output = file_get_contents($this->file);
106                    if (strpos($output, '<?xml version') === false) {
107                        $output = '<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL .
108                            '<log>' . PHP_EOL . '</log>' . PHP_EOL;
109                    }
110
111                    $messageContext = $this->getContext($context);
112
113                    $entry  = ($messageContext != '') ?
114                        '    <entry timestamp="' . $context['timestamp'] . '" priority="' .
115                        $level . '" name="' . $context['name'] . '" context="' . $messageContext .
116                        '"><![CDATA[' . $message . ']]></entry>' . PHP_EOL :
117                        '    <entry timestamp="' . $context['timestamp'] . '" priority="' .
118                        $level . '" name="' . $context['name'] . '"><![CDATA[' . $message . ']]></entry>' . PHP_EOL;
119
120                    $output = str_replace('</log>' . PHP_EOL, $entry . '</log>' . PHP_EOL, $output);
121                    file_put_contents($this->file, $output);
122                    break;
123
124                case 'json':
125                    $output = file_get_contents($this->file);
126                    $json = (strpos($output, '{') !== false) ?
127                        json_decode($output, true) : [];
128
129                    $messageContext = $this->getContext($context);
130
131                    $json[] = [
132                        'timestamp' => $context['timestamp'],
133                        'priority'  => $level,
134                        'name'      => $context['name'],
135                        'message'   => $message,
136                        'context'   => $messageContext
137                    ];
138
139                    file_put_contents($this->file, json_encode($json, JSON_PRETTY_PRINT));
140                    break;
141
142                default:
143                    $entry = $context['timestamp'] . "\t" . $level . "\t" .
144                        $context['name'] . "\t" . $message . "\t" . $this->getContext($context) . PHP_EOL;
145                    file_put_contents($this->file, $entry, FILE_APPEND);
146            }
147        }
148
149        return $this;
150    }
151
152}