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

systemsdk / phpcpd / #12

13 Apr 2025 04:42PM UTC coverage: 75.711%. Remained the same
#12

push

DKravtsov
phpcpd 8.1.1 release. Available installation via composer.

692 of 914 relevant lines covered (75.71%)

3.7 hits per line

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

60.0
/src/Log/AbstractXmlLogger.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Systemsdk\PhpCPD\Log;
6

7
use DOMDocument;
8
use Systemsdk\PhpCPD\CodeCloneMap;
9
use Systemsdk\PhpCPD\Exceptions\LoggerException;
10

11
use function file_put_contents;
12
use function htmlspecialchars;
13
use function mb_convert_encoding;
14
use function ord;
15
use function preg_replace;
16
use function strlen;
17

18
use const ENT_COMPAT;
19

20
abstract class AbstractXmlLogger
21
{
22
    protected DOMDocument $document;
23

24
    public function __construct(
25
        private readonly string $filename
26
    ) {
27
        $this->document = new DOMDocument('1.0', 'UTF-8');
1✔
28
        $this->document->formatOutput = true;
1✔
29
    }
30

31
    abstract public function processClones(CodeCloneMap $clones): void;
32

33
    /**
34
     * @throws LoggerException
35
     */
36
    protected function flush(): void
37
    {
38
        $xml = $this->document->saveXML();
1✔
39

40
        if ($xml === false) {
1✔
41
            throw new LoggerException('Can not dump the internal xml tree back into a string');
×
42
        }
43

44
        $results = file_put_contents($this->filename, $xml);
1✔
45

46
        if ($results === false) {
1✔
47
            throw new LoggerException('Can not save log file');
×
48
        }
49
    }
50

51
    /**
52
     * @throws LoggerException
53
     */
54
    protected function convertToUtf8(string $string): string
55
    {
56
        if (!$this->isUtf8($string)) {
1✔
57
            /** @var string|false $string */
58
            $string = mb_convert_encoding($string, 'UTF-8');
×
59

60
            if ($string === false) {
×
61
                throw new LoggerException('Cannot convert to UTF-8');
×
62
            }
63
        }
64

65
        return (string)$string;
1✔
66
    }
67

68
    protected function isUtf8(string $string): bool
69
    {
70
        $length = strlen($string);
1✔
71

72
        for ($i = 0; $i < $length; $i++) {
1✔
73
            if (ord($string[$i]) < 0x80) {
1✔
74
                $n = 0;
1✔
75
            } elseif ((ord($string[$i]) & 0xE0) === 0xC0) {
×
76
                $n = 1;
×
77
            } elseif ((ord($string[$i]) & 0xF0) === 0xE0) {
×
78
                $n = 2;
×
79
            } elseif ((ord($string[$i]) & 0xF0) === 0xF0) {
×
80
                $n = 3;
×
81
            } else {
82
                return false;
×
83
            }
84

85
            for ($j = 0; $j < $n; $j++) {
1✔
86
                if ((++$i === $length) || ((ord($string[$i]) & 0xC0) !== 0x80)) {
×
87
                    return false;
×
88
                }
89
            }
90
        }
91

92
        return true;
1✔
93
    }
94

95
    /**
96
     * @throws LoggerException
97
     */
98
    protected function escapeForXml(string $string): string
99
    {
100
        $string = $this->convertToUtf8($string);
1✔
101
        $string = (string)preg_replace(
1✔
102
            '/[^\x09\x0A\x0D\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]/u',
1✔
103
            "\xEF\xBF\xBD",
1✔
104
            $string
1✔
105
        );
1✔
106

107
        return htmlspecialchars($string, ENT_COMPAT);
1✔
108
    }
109
}
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