Translator::logUntranslatedMessage()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 1
c 3
b 0
f 1
dl 0
loc 2
rs 10
ccs 1
cts 1
cp 1
cc 1
nc 1
nop 1
crap 1
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
?>