Translator   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 29
Bugs 1 Features 4
Metric Value
wmc 17
eloc 43
c 29
b 1
f 4
dl 0
loc 96
ccs 39
cts 39
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A extractDomainAndMessage() 0 5 2
A getUntranslated() 0 2 1
A __construct() 0 3 1
A setLang() 0 2 1
A getLang() 0 2 1
A logUntranslatedMessage() 0 2 1
A multiLevelTrans() 0 10 3
B translate() 0 27 7
1
<?php
2
declare(strict_types=1);
3
4
namespace Nexendrie\Translation;
5
6
use Nette\Utils\Arrays;
7
use Nette\Localization\ITranslator;
8
9
/**
10
 * Translator
11
 *
12
 * @author Jakub Konečný
13
 * @property string $lang
14
 * @property-read string[] $untranslated
15
 * @method void onUntranslated(string $message)
16
 */
17 1
final class Translator implements ITranslator {
0 ignored issues
show
Deprecated Code introduced by
The interface Nette\Localization\ITranslator has been deprecated: use Nette\Localization\Translator ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

17
final class Translator implements /** @scrutinizer ignore-deprecated */ ITranslator {

This interface has been deprecated. The supplier of the interface has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.

Loading history...
18
  use \Nette\SmartObject;
19
  
20
  /** @internal */
21
  public const DEFAULT_DOMAIN = "messages";
22
23
  private ILoader $loader;
24
  private IMessageSelector $messageSelector;
25
  /** @var string[] */
26
  private array $untranslated = [];
27
  /** @var callable[] */
28
  public array $onUntranslated = [];
29
  
30
  public function __construct(ILoader $loader, IMessageSelector $messageSelector = null) {
31 1
    $this->loader = $loader;
32 1
    $this->messageSelector = $messageSelector ?? new MessageSelector();
33 1
  }
34
  
35
  public function getLang(): string {
36 1
    return $this->loader->getLang();
37
  }
38
  
39
  public function setLang(string $lang): void {
40 1
    $this->loader->setLang($lang);
41 1
  }
42
  
43
  /**
44
   * @return string[]
45
   */
46
  public function getUntranslated(): array {
47 1
    return $this->untranslated;
48
  }
49
  
50
  /**
51
   * @return string[]
52
   */
53
  protected function extractDomainAndMessage(string $message): array {
54 1
    if(!str_contains($message, ".")) {
55 1
      return [static::DEFAULT_DOMAIN, $message];
56
    }
57 1
    return explode(".", $message, 2);
58
  }
59
  
60
  /**
61
   * Translate multi-level message
62
   */
63
  protected function multiLevelTrans(array $message, array $texts): string {
64 1
    $text = $texts;
65 1
    foreach($message as $part) {
66 1
      $text = Arrays::get($text, $part, "");
67 1
      if($text === "") {
68 1
        break;
69
      }
70
    }
71
    /** @var string $text */
72 1
    return $text;
73
  }
74
  
75
  public function logUntranslatedMessage(string $message): void {
76 1
    $this->untranslated[] = $message;
77 1
  }
78
79
  /**
80
   * Translate the string
81
   *
82
   * @param mixed $message
83
   * @param mixed ...$parameters
84
   * @return string
85
   */
86
  public function translate($message, ... $parameters): string {
87 1
    $message = (string) $message;
88 1
    if(count($parameters) === 1 && is_array($parameters[0])) {
89 1
      $count = $parameters[0]["count"] ?? 0;
90 1
      $params = $parameters[0];
91
    } else {
92 1
      $params = $parameters[1] ?? [];
93 1
      $params["count"] = $count = $parameters[0] ?? 0;
94
    }
95 1
    [$domain, $m] = $this->extractDomainAndMessage($message);
96 1
    $texts = Arrays::get($this->loader->getTexts(), $domain, []);
97 1
    $parts = explode(".", $m);
98 1
    if(count($parts) === 1) {
99 1
      $parts = [$m];
100
    }
101 1
    $text = $this->multiLevelTrans($parts, $texts);
0 ignored issues
show
Bug introduced by
$texts of type Nette\Utils\T|null is incompatible with the type array expected by parameter $texts of Nexendrie\Translation\Tr...ator::multiLevelTrans(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
    $text = $this->multiLevelTrans($parts, /** @scrutinizer ignore-type */ $texts);
Loading history...
102 1
    if($text === "") {
103 1
      $this->onUntranslated($message);
104 1
      return $message;
105
    }
106 1
    if($this->messageSelector->isMultiChoice($text)) {
107 1
      $text = $this->messageSelector->choose($text, $count);
108
    }
109 1
    foreach($params as $key => $value) {
110 1
      $text = str_replace("%$key%", (string) $value, $text);
111
    }
112 1
    return $text;
113
  }
114
}
115
?>