Translator   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 26
Bugs 0 Features 4
Metric Value
wmc 17
eloc 42
c 26
b 0
f 4
dl 0
loc 94
rs 10
ccs 39
cts 39
cp 1

8 Methods

Rating   Name   Duplication   Size   Complexity  
A extractDomainAndMessage() 0 5 2
A getUntranslated() 0 2 1
A logUntranslatedMessage() 0 2 1
A multiLevelTrans() 0 9 3
A __construct() 0 3 1
A setLang() 0 2 1
A getLang() 0 2 1
B translate() 0 26 7
1
<?php
2
declare(strict_types=1);
3
4
namespace Nexendrie\Translation;
5
6
use Nette\Utils\Arrays;
7
use Nette\Utils\Strings;
8
use Nette\Localization\ITranslator;
9
10
/**
11
 * Translator
12
 *
13
 * @author Jakub Konečný
14
 * @property string $lang
15
 * @property-read string[] $untranslated
16
 * @method void onUntranslated(string $message)
17
 */
18 1
final class Translator implements ITranslator {
19 1
  use \Nette\SmartObject;
20
  
21
  /** @internal */
22
  public const DEFAULT_DOMAIN = "messages";
23
  
24
  /** @var ILoader */
25
  protected $loader;
26
  /** @var IMessageSelector */
27
  protected $messageSelector;
28
  /** @var string[] */
29
  protected $untranslated = [];
30
  /** @var callable[] */
31
  public $onUntranslated = [];
32
  
33
  public function __construct(ILoader $loader, IMessageSelector $messageSelector = null) {
34 1
    $this->loader = $loader;
35 1
    $this->messageSelector = $messageSelector ?? new MessageSelector();
36 1
  }
37
  
38
  public function getLang(): string {
39 1
    return $this->loader->getLang();
40
  }
41
  
42
  public function setLang(string $lang): void {
43 1
    $this->loader->setLang($lang);
44 1
  }
45
  
46
  /**
47
   * @return string[]
48
   */
49
  public function getUntranslated(): array {
50 1
    return $this->untranslated;
51
  }
52
  
53
  /**
54
   * @return string[]
55
   */
56
  protected function extractDomainAndMessage(string $message): array {
57 1
    if(!Strings::contains($message, ".")) {
58 1
      return [static::DEFAULT_DOMAIN, $message];
59
    }
60 1
    return explode(".", $message, 2);
61
  }
62
  
63
  /**
64
   * Translate multi-level message
65
   */
66
  protected function multiLevelTrans(array $message, array $texts): string {
67 1
    $text = $texts;
68 1
    foreach($message as $part) {
69 1
      $text = Arrays::get($text, $part, "");
70 1
      if($text === "") {
71 1
        break;
72
      }
73
    }
74 1
    return $text;
75
  }
76
  
77
  public function logUntranslatedMessage(string $message): void {
78 1
    $this->untranslated[] = $message;
79 1
  }
80
  
81
  /**
82
   * Translate the string
83
   *
84
   * @param string $message
85
   */
86
  public function translate($message, ... $parameters): string {
87 1
    if(count($parameters) === 1 && is_array($parameters[0])) {
88 1
      $count = $parameters[0]["count"] ?? 0;
89 1
      $params = $parameters[0];
90
    } else {
91 1
      $params = $parameters[1] ?? [];
92 1
      $params["count"] = $count = $parameters[0] ?? 0;
93
    }
94 1
    list($domain, $m) = $this->extractDomainAndMessage($message);
95 1
    $texts = Arrays::get($this->loader->getTexts(), $domain, []);
96 1
    $parts = explode(".", $m);
97 1
    if(count($parts) === 1) {
98 1
      $parts = [$m];
99
    }
100 1
    $text = $this->multiLevelTrans($parts, $texts);
101 1
    if($text === "") {
102 1
      $this->onUntranslated($message);
103 1
      return $message;
104
    }
105 1
    if($this->messageSelector->isMultiChoice($text)) {
106 1
      $text = $this->messageSelector->choose($text, $count);
107
    }
108 1
    foreach($params as $key => $value) {
109 1
      $text = str_replace("%$key%", $value, $text);
110
    }
111 1
    return $text;
112
  }
113
}
114
?>