/Model/Message.php

https://github.com/schmittjoh/JMSTranslationBundle · PHP · 409 lines · 169 code · 55 blank · 185 comment · 15 complexity · 53a04bb7eb2c1ef4e5a641697c79c219 MD5 · raw file

  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. namespace JMS\TranslationBundle\Model;
  19. use JMS\TranslationBundle\Exception\RuntimeException;
  20. /**
  21. * Represents an _extracted_ message.
  22. *
  23. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  24. */
  25. class Message
  26. {
  27. /**
  28. * Unique ID of this message (same across the same domain).
  29. *
  30. * @var string
  31. */
  32. private $id;
  33. /**
  34. * @var bool
  35. */
  36. private $new = true;
  37. /**
  38. * @var string
  39. */
  40. private $domain;
  41. /**
  42. * This is the translated string.
  43. *
  44. * @var string
  45. */
  46. private $localeString;
  47. /**
  48. * Additional information about the intended meaning.
  49. *
  50. * @var string
  51. */
  52. private $meaning;
  53. /**
  54. * The description/sample for translators.
  55. *
  56. * @var string
  57. */
  58. private $desc;
  59. /**
  60. * The sources where this message occurs.
  61. *
  62. * @var array
  63. */
  64. private $sources = [];
  65. /**
  66. * @deprecated Will be removed in 2.0. Use the FileSourceFactory
  67. *
  68. * @param string $id
  69. * @param string $domain
  70. *
  71. * @return Message
  72. *
  73. * @static
  74. */
  75. public static function forThisFile($id, $domain = 'messages')
  76. {
  77. $message = new static($id, $domain);
  78. $trace = debug_backtrace(0);
  79. if (isset($trace[0]['file'])) {
  80. $message->addSource(new FileSource($trace[0]['file']));
  81. }
  82. return $message;
  83. }
  84. /**
  85. * @param string $id
  86. * @param string $domain
  87. *
  88. * @return static
  89. *
  90. * @static
  91. */
  92. public static function create($id, $domain = 'messages')
  93. {
  94. return new static($id, $domain);
  95. }
  96. /**
  97. * @param string $id
  98. * @param string $domain
  99. */
  100. public function __construct($id, $domain = 'messages')
  101. {
  102. $this->id = (string) $id;
  103. $this->domain = $domain;
  104. }
  105. /**
  106. * @param SourceInterface $source
  107. *
  108. * @return Message
  109. */
  110. public function addSource(SourceInterface $source)
  111. {
  112. if ($this->hasSource($source)) {
  113. return $this;
  114. }
  115. $this->sources[] = $source;
  116. return $this;
  117. }
  118. /**
  119. * @return string
  120. */
  121. public function getId()
  122. {
  123. return $this->id;
  124. }
  125. /**
  126. * @return string
  127. */
  128. public function getDomain()
  129. {
  130. return $this->domain;
  131. }
  132. /**
  133. * @return bool
  134. */
  135. public function isNew()
  136. {
  137. return $this->new;
  138. }
  139. /**
  140. * This will return:
  141. * 1) the localeString, ie the translated string
  142. * 2) description (if new)
  143. * 3) id (if new)
  144. * 4) empty string.
  145. *
  146. * @return string
  147. */
  148. public function getLocaleString()
  149. {
  150. return $this->localeString ?? ($this->new ? ($this->desc ?? $this->id) : '');
  151. }
  152. /**
  153. * Returns the string from which to translate.
  154. *
  155. * This typically is the description, but we will fallback to the id
  156. * if that has not been given.
  157. *
  158. * @return string
  159. */
  160. public function getSourceString()
  161. {
  162. return $this->desc ?: $this->id;
  163. }
  164. /**
  165. * @return string
  166. */
  167. public function getMeaning()
  168. {
  169. return $this->meaning;
  170. }
  171. /**
  172. * @return string
  173. */
  174. public function getDesc()
  175. {
  176. return $this->desc;
  177. }
  178. /**
  179. * @return array
  180. */
  181. public function getSources()
  182. {
  183. return $this->sources;
  184. }
  185. /**
  186. * @param string $meaning
  187. *
  188. * @return $this
  189. */
  190. public function setMeaning($meaning)
  191. {
  192. $this->meaning = $meaning;
  193. return $this;
  194. }
  195. /**
  196. * @param bool $bool
  197. *
  198. * @return $this
  199. */
  200. public function setNew($bool)
  201. {
  202. $this->new = (bool) $bool;
  203. return $this;
  204. }
  205. /**
  206. * @param string $desc
  207. *
  208. * @return $this
  209. */
  210. public function setDesc($desc)
  211. {
  212. $this->desc = $desc;
  213. return $this;
  214. }
  215. /**
  216. * @param string $str
  217. *
  218. * @return $this
  219. */
  220. public function setLocaleString($str)
  221. {
  222. $this->localeString = $str;
  223. return $this;
  224. }
  225. public function setSources(array $sources = [])
  226. {
  227. $this->sources = $sources;
  228. return $this;
  229. }
  230. /**
  231. * Return true if we have a translated string. This is not the same as running:
  232. * $str = $message->getLocaleString();
  233. * $bool = !empty($str);.
  234. *
  235. * The $message->getLocaleString() will return a description or an id if the localeString does not exist.
  236. *
  237. * @return bool
  238. */
  239. public function hasLocaleString()
  240. {
  241. return !empty($this->localeString);
  242. }
  243. /**
  244. * Merges an extracted message.
  245. *
  246. * Do not use this if you want to merge a message from an existing catalogue.
  247. * In these cases, use mergeExisting() instead.
  248. *
  249. * @param Message $message
  250. *
  251. * @throws RuntimeException
  252. */
  253. public function merge(Message $message)
  254. {
  255. if ($this->id !== $message->getId()) {
  256. throw new RuntimeException(sprintf('You can only merge messages with the same id. Expected id "%s", but got "%s".', $this->id, $message->getId()));
  257. }
  258. if (null !== $meaning = $message->getMeaning()) {
  259. $this->meaning = $meaning;
  260. }
  261. if (null !== $desc = $message->getDesc()) {
  262. $this->desc = $desc;
  263. $this->localeString = null;
  264. if ($message->hasLocaleString()) {
  265. $this->localeString = $message->getLocaleString();
  266. }
  267. }
  268. foreach ($message->getSources() as $source) {
  269. $this->addSource($source);
  270. }
  271. $this->setNew($message->isNew());
  272. }
  273. /**
  274. * Merges a message from an existing translation catalogue.
  275. *
  276. * Do not use this if you want to merge a message from an extracted catalogue.
  277. * In these cases, use merge() instead.
  278. *
  279. * @deprecated not in use atm
  280. *
  281. * @param Message $message
  282. */
  283. public function mergeExisting(Message $message)
  284. {
  285. if ($this->id !== $message->getId()) {
  286. throw new RuntimeException(sprintf('You can only merge messages with the same id. Expected id "%s", but got "%s".', $this->id, $message->getId()));
  287. }
  288. if (null !== $meaning = $message->getMeaning()) {
  289. $this->meaning = $meaning;
  290. }
  291. if (null !== $desc = $message->getDesc()) {
  292. $this->desc = $desc;
  293. }
  294. $this->setNew($message->isNew());
  295. if ($localeString = $message->getLocaleString()) {
  296. $this->localeString = $localeString;
  297. }
  298. }
  299. /**
  300. * Merge a scanned message into an extising message.
  301. *
  302. * This method does essentially the same as {@link mergeExisting()} but with reversed operands.
  303. * Whereas {@link mergeExisting()} is used to merge an existing message into a scanned message (this),
  304. * {@link mergeScanned()} is used to merge a scanned message into an existing message (this).
  305. * The result of both methods is the same, except that the result will end up in the existing message,
  306. * instead of the scanned message, so extra information read from the existing message is not discarded.
  307. *
  308. * @author Dieter Peeters <peetersdiet@gmail.com>
  309. *
  310. * @param Message $message
  311. */
  312. public function mergeScanned(Message $message)
  313. {
  314. if ($this->id !== $message->getId()) {
  315. throw new RuntimeException(sprintf('You can only merge messages with the same id. Expected id "%s", but got "%s".', $this->id, $message->getId()));
  316. }
  317. if (null === $this->getMeaning()) {
  318. $this->meaning = $message->getMeaning();
  319. }
  320. if (null === $this->getDesc()) {
  321. $this->desc = $message->getDesc();
  322. }
  323. $this->sources = [];
  324. foreach ($message->getSources() as $source) {
  325. $this->addSource($source);
  326. }
  327. if (!$this->getLocaleString()) {
  328. $this->localeString = $message->getLocaleString();
  329. }
  330. }
  331. /**
  332. * @param SourceInterface $source
  333. *
  334. * @return bool
  335. */
  336. public function hasSource(SourceInterface $source)
  337. {
  338. foreach ($this->sources as $cSource) {
  339. if ($cSource->equals($source)) {
  340. return true;
  341. }
  342. }
  343. return false;
  344. }
  345. /**
  346. * Allows us to use this with existing message catalogues.
  347. *
  348. * @return string
  349. */
  350. public function __toString()
  351. {
  352. return $this->id;
  353. }
  354. }