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

move-elevator / composer-translation-validator / 18559956393

16 Oct 2025 11:36AM UTC coverage: 95.519%. Remained the same
18559956393

Pull #73

github

jackd248
Merge remote-tracking branch 'origin/main' into php-cs-fixer-preset
Pull Request #73: build: add php-cs-fixer-preset

206 of 210 new or added lines in 16 files covered. (98.1%)

91 existing lines in 20 files now uncovered.

2345 of 2455 relevant lines covered (95.52%)

7.73 hits per line

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

97.67
/src/Parser/XliffParser.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the "composer-translation-validator" Composer plugin.
7
 *
8
 * (c) 2025 Konrad Michalik <km@move-elevator.de>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace MoveElevator\ComposerTranslationValidator\Parser;
15

16
use InvalidArgumentException;
17
use SimpleXMLElement;
18

19
/**
20
 * XliffParser.
21
 *
22
 * @author Konrad Michalik <km@move-elevator.de>
23
 * @license GPL-3.0-or-later
24
 */
25
class XliffParser extends AbstractParser implements ParserInterface
26
{
27
    private readonly SimpleXMLElement|bool $xml;
28

29
    /**
30
     * @param string $filePath Path to the XLIFF file
31
     *
32
     * @throws InvalidArgumentException If file cannot be parsed as
33
     *                                  valid XML
34
     */
35
    public function __construct(string $filePath)
16✔
36
    {
37
        parent::__construct($filePath);
16✔
38

39
        $xmlContent = file_get_contents($filePath);
13✔
40
        if (false === $xmlContent) {
13✔
UNCOV
41
            throw new InvalidArgumentException("Failed to read file: {$filePath}");
×
42
        }
43

44
        libxml_use_internal_errors(true);
13✔
45
        $this->xml = simplexml_load_string($xmlContent);
13✔
46

47
        if (false === $this->xml) {
13✔
48
            throw new InvalidArgumentException("Failed to parse XML content from file: {$filePath}");
1✔
49
        }
50
        libxml_clear_errors();
12✔
51
    }
52

53
    /**
54
     * @return array<int, string>|null
55
     */
56
    public function extractKeys(): ?array
1✔
57
    {
58
        $keys = [];
1✔
59
        foreach ($this->xml->file->body->{'trans-unit'} as $unit) {
1✔
60
            $keys[] = (string) $unit['id'];
1✔
61
        }
62

63
        return $keys;
1✔
64
    }
65

66
    public function getContentByKey(string $key): ?string
5✔
67
    {
68
        $attribute = $this->hasTargetLanguage() ? 'target' : 'source';
5✔
69

70
        foreach ($this->xml->file->body->{'trans-unit'} as $unit) {
5✔
71
            if ((string) $unit['id'] === $key) {
5✔
72
                if ('' !== (string) $unit->{$attribute}) {
5✔
73
                    return (string) $unit->{$attribute};
2✔
74
                }
75

76
                if ('target' === $attribute && $this->hasTargetLanguage()) {
4✔
77
                    $fallbackContent = (string) $unit->source;
3✔
78
                    if ('' !== $fallbackContent) {
3✔
79
                        return $fallbackContent;
2✔
80
                    }
81
                }
82

83
                if ('source' === $attribute && !$this->hasTargetLanguage()) {
2✔
84
                    $fallbackContent = (string) $unit->target;
1✔
85
                    if ('' !== $fallbackContent) {
1✔
86
                        return $fallbackContent;
1✔
87
                    }
88
                }
89
            }
90
        }
91

92
        return null;
3✔
93
    }
94

95
    /**
96
     * @return array<int, string>
97
     */
98
    public static function getSupportedFileExtensions(): array
27✔
99
    {
100
        return ['xliff', 'xlf'];
27✔
101
    }
102

103
    public function getLanguage(): string
3✔
104
    {
105
        if (preg_match(
3✔
106
            '/^([a-z]{2})\./i',
3✔
107
            $this->getFileName(),
3✔
108
            $matches,
3✔
109
        )) {
3✔
110
            $language = $matches[1];
1✔
111
        } else {
112
            $language = (string) ($this->xml->file['source-language'] ?? '');
2✔
113
        }
114

115
        return $language;
3✔
116
    }
117

118
    private function hasTargetLanguage(): bool
5✔
119
    {
120
        return !empty((string) $this->xml->file['target-language']);
5✔
121
    }
122
}
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

© 2025 Coveralls, Inc