Lines
91.48%
43 / 47
Methods
40.00%
2 / 5
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| getStatistics | 93.10% | 27 / 29 | 0.00% | 0 / 1 | 6.01 | ||
| getLanguageStatistics | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 1 | ||
| getMissingKeys | 100.00% | 5 / 5 | 100.00% | 1 / 1 | 2 | ||
| getTranslationKeys | 85.71% | 6 / 7 | 0.00% | 0 / 1 | 2.01 | ||
| extractLanguageCode | 75.00% | 3 / 4 | 0.00% | 0 / 1 | 2.06 | ||
| 22 | readonly class TranslationStatistics | |
| 23 | { | |
| 24 | private const string REFERENCE_LANGUAGE = 'en'; | |
| 25 | ||
| 26 | /** | |
| 27 | * Returns statistics about all available translations. | |
| 28 | * | |
| 29 | * @return array<string, array<string, mixed>> | |
| 30 | */ | |
| 31 | public function getStatistics(): array | |
| 32 | { | |
| 33 | $statistics = []; | |
| 34 | $translationsDir = PMF_TRANSLATION_DIR; | |
| 35 | $referenceKeys = $this->getTranslationKeys(self::REFERENCE_LANGUAGE); | |
| 36 | $totalReferenceKeys = count($referenceKeys); | |
| 37 | ||
| 38 | $languageFiles = glob($translationsDir . '/language_*.php'); | |
| 39 | ||
| 40 | if ($languageFiles === false) { | |
| 41 | return $statistics; | |
| 42 | } | |
| 43 | ||
| 44 | foreach ($languageFiles as $languageFile) { | |
| 45 | $language = $this->extractLanguageCode($languageFile); | |
| 46 | ||
| 47 | if ($language === null) { | |
| 48 | continue; | |
| 49 | } | |
| 50 | ||
| 51 | $translationKeys = $this->getTranslationKeys($language); | |
| 52 | $totalKeys = count($translationKeys); | |
| 53 | $missingKeys = array_diff($referenceKeys, $translationKeys); | |
| 54 | $missingCount = count($missingKeys); | |
| 55 | $translatedCount = $totalKeys; | |
| 56 | ||
| 57 | if ($language !== self::REFERENCE_LANGUAGE) { | |
| 58 | $translatedCount = $totalReferenceKeys - $missingCount; | |
| 59 | } | |
| 60 | ||
| 61 | $statistics[$language] = [ | |
| 62 | 'language_code' => $language, | |
| 63 | 'total_keys' => $totalKeys, | |
| 64 | 'translated_keys' => $translatedCount, | |
| 65 | 'missing_keys' => $missingCount, | |
| 66 | 'completion_percentage' => $totalReferenceKeys > 0 | |
| 67 | ? round(($translatedCount / $totalReferenceKeys) * 100, precision: 2) | |
| 68 | : 0.0, | |
| 69 | ]; | |
| 70 | } | |
| 71 | ||
| 72 | uasort($statistics, static fn($a, $b): int => $b['completion_percentage'] <=> $a['completion_percentage']); | |
| 73 | ||
| 74 | return $statistics; | |
| 75 | } | |
| 76 | ||
| 77 | /** | |
| 78 | * Returns detailed statistics for a specific language. | |
| 79 | * | |
| 80 | * @return array<string, mixed>|null | |
| 81 | */ | |
| 82 | public function getLanguageStatistics(string $language): ?array | |
| 83 | { | |
| 84 | $statistics = $this->getStatistics(); | |
| 85 | ||
| 86 | return $statistics[$language] ?? null; | |
| 87 | } | |
| 88 | ||
| 89 | /** | |
| 90 | * Returns the list of missing translation keys for a specific language. | |
| 91 | * | |
| 92 | * @return array<int, string> | |
| 93 | */ | |
| 94 | public function getMissingKeys(string $language): array | |
| 95 | { | |
| 96 | if ($language === self::REFERENCE_LANGUAGE) { | |
| 97 | return []; | |
| 98 | } | |
| 99 | ||
| 100 | $referenceKeys = $this->getTranslationKeys(self::REFERENCE_LANGUAGE); | |
| 101 | $languageKeys = $this->getTranslationKeys($language); | |
| 102 | ||
| 103 | return array_values(array_diff($referenceKeys, $languageKeys)); | |
| 104 | } | |
| 105 | ||
| 106 | /** | |
| 107 | * Returns all translation keys for a specific language. | |
| 108 | * | |
| 109 | * @return array<int, string> | |
| 110 | */ | |
| 111 | private function getTranslationKeys(string $language): array | |
| 112 | { | |
| 113 | $translationsDir = PMF_TRANSLATION_DIR; | |
| 114 | $file = $translationsDir . '/language_' . $language . '.php'; | |
| 115 | ||
| 116 | if (!file_exists($file)) { | |
| 117 | return []; | |
| 118 | } | |
| 119 | ||
| 120 | $PMF_LANG = []; | |
| 121 | include $file; | |
| 122 | ||
| 123 | return array_map(strval(...), array_keys($PMF_LANG)); | |
| 124 | } | |
| 125 | ||
| 126 | /** | |
| 127 | * Extracts the language code from a translation file path. | |
| 128 | */ | |
| 129 | private function extractLanguageCode(string $filePath): ?string | |
| 130 | { | |
| 131 | $matches = []; | |
| 132 | if (preg_match(pattern: '/language_([a-z_]+)\.php$/', subject: $filePath, matches: $matches)) { | |
| 133 | return $matches[1]; | |
| 134 | } | |
| 135 | ||
| 136 | return null; | |
| 137 | } | |
| 138 | } |