• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

The-oGlow / ezlogging / 21788760591

07 Feb 2026 11:36PM UTC coverage: 81.481% (+0.5%) from 81.0%
21788760591

push

github

ollily
#1: add  / tested

45 of 54 new or added lines in 10 files covered. (83.33%)

52 existing lines in 4 files now uncovered.

374 of 459 relevant lines covered (81.48%)

12.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/src/Monolog/Handler/CsvHandler.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of ezlogging
7
 *
8
 * (c) 2025 Oliver Glowa, coding.glowa.com
9
 *
10
 * This source file is subject to the Apache-2.0 license that is bundled
11
 * with this source code in the file LICENSE.
12
 */
13

14
namespace Monolog\Handler;
15

16
use ollily\Tools\PhpVersionTrait;
17
use ollily\Tools\String\ImplodeTrait;
18

19
/**
20
 * Stores any data (given as array) to a csv file.
21
 *
22
 * Inspired by {@see https://github.com/femtopixel/monolog-csvhandler}.
23
 * Original by @author Jay MOULIN <jay@femtopixel.com>
24
 *
25
 * @see FileHandler
26
 */
27
class CsvHandler extends FileHandler
28
{
29
    use PhpVersionTrait;
30
    use ImplodeTrait;
31

32
    /** @var string Fallback filename */
33
    public const    STANDARD_FILENAME = 'noCSVName';
34

35
    /** @var string Default file extension */
36
    public const    STANDARD_FILEEXT     = '.csv';
37

38
    /** @var string Default separator char for each column */
39
    public const    STANDARD_ITEM_SEP    = ';';
40

41
    /** @var string Default char enclosing each column value */
42
    public const    STANDARD_TEXT_SEP    = '"';
43

44
    /** @var string Default char for escaping char */
45
    public const    STANDARD_ESCAPE_CHAR = '\\';
46

47
    /** var string Relevant PHP version */
48
    protected const CHECKVERSION = '5.5.4';
49

50
    /** @var string Key of the formatted in the output record */
51
    protected const KEY_FORMATTED        = 'formatted';
52

53
    /** @var string The separator char for each column */
54
    private $itemSeparator;
55

56
    /** @var string The char enclosing each column value */
57
    private $itemEnclosure;
58

59
    /**
60
     * CsvHandler constructor.
61
     *
62
     * @param null|string $pathToFile    The full path to the output folder
63
     * @param null|string $fileName      The name of the output file
64
     * @param string      $itemSeparator The separator char for each column (Default: {@link CsvHandler::STANDARD_ITEM_SEP})
65
     * @param string      $itemEnclosure The char enclosing each column value (Default: {@link CsvHandler::STANDARD_TEXT_SEP})
66
     * @param mixed       $level         The output level (Default: {@link FileHandler::LEVEL_DEFAULT})
67
     *
68
     * @see CsvHandler::STANDARD_ITEM_SEP
69
     * @see CsvHandler::STANDARD_TEXT_SEP
70
     * @see FileHandler::LEVEL_DEFAULT
71
     */
72
    public function __construct(
22✔
73
        ?string $pathToFile = null,
74
        ?string $fileName = null,
75
        string $itemSeparator = self::STANDARD_ITEM_SEP,
76
        string $itemEnclosure = self::STANDARD_TEXT_SEP,
77
        $level = self::LEVEL_DEFAULT
78
    ) {
79
        parent::__construct($pathToFile, $fileName, $level);
22✔
80
        $this->itemSeparator = $itemSeparator;
22✔
81
        $this->itemEnclosure = $itemEnclosure;
22✔
82
    }
83

84
    /**
85
     * @inheritdoc
86
     */
87
    protected function streamWrite($stream, array $record): void
13✔
88
    {
89
        $output = [];
13✔
90
        // @phpstan-ignore isset.offset
91
        if (isset($record[self::KEY_MESSAGE]) && !empty($record[self::KEY_MESSAGE])) {
13✔
92
            array_push($output, $record[self::KEY_MESSAGE]);
10✔
93
        }
94

95
        // @phpstan-ignore isset.offset
96
        if (isset($record[self::KEY_CONTEXT]) && !empty($record[self::KEY_CONTEXT])) {
13✔
97
            $implodeContext = $record[self::KEY_CONTEXT];
10✔
98
            /**
99
             * @psalm-suppress RedundantCondition
100
             * @phpstan-ignore if.alwaysTrue
101
             */
102
            if (is_array($record[self::KEY_CONTEXT])) {
10✔
103
                $implodeContext = $this->array_flatten($record[self::KEY_CONTEXT]);
10✔
104
            }
105
            $output = array_merge($output, $implodeContext);
10✔
106
        }
107
        if ($this->isPhpGreater(self::CHECKVERSION)) {
13✔
108
            fputcsv($stream, $output, $this->itemSeparator, $this->itemEnclosure, static::STANDARD_ESCAPE_CHAR);
13✔
109
        } else {
UNCOV
110
            fputcsv($stream, $output, $this->itemSeparator, $this->itemEnclosure);
×
111
        }
112
    }
113
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc