PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/website/library/Zend/Translate/Adapter.php

https://bitbucket.org/efdac/e-forest_platform
PHP | 931 lines | 553 code | 108 blank | 270 comment | 155 complexity | d386f50c88ca3b4a2243fd684d411542 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Translate
  17. * @subpackage Zend_Translate_Adapter
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Adapter.php 22425 2010-06-12 20:40:46Z thomas $
  21. */
  22. /**
  23. * @see Zend_Locale
  24. */
  25. require_once 'Zend/Locale.php';
  26. /**
  27. * @see Zend_Translate_Plural
  28. */
  29. require_once 'Zend/Translate/Plural.php';
  30. /**
  31. * Basic adapter class for each translation source adapter
  32. *
  33. * @category Zend
  34. * @package Zend_Translate
  35. * @subpackage Zend_Translate_Adapter
  36. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  37. * @license http://framework.zend.com/license/new-bsd New BSD License
  38. */
  39. abstract class Zend_Translate_Adapter {
  40. /**
  41. * Shows if locale detection is in automatic level
  42. * @var boolean
  43. */
  44. private $_automatic = true;
  45. /**
  46. * Internal value to see already routed languages
  47. * @var array()
  48. */
  49. private $_routed = array();
  50. /**
  51. * Internal cache for all adapters
  52. * @var Zend_Cache_Core
  53. */
  54. protected static $_cache = null;
  55. /**
  56. * Scans for the locale within the name of the directory
  57. * @constant integer
  58. */
  59. const LOCALE_DIRECTORY = 'directory';
  60. /**
  61. * Scans for the locale within the name of the file
  62. * @constant integer
  63. */
  64. const LOCALE_FILENAME = 'filename';
  65. /**
  66. * Array with all options, each adapter can have own additional options
  67. * 'clear' => when true, clears already loaded translations when adding new files
  68. * 'content' => content to translate or file or directory with content
  69. * 'disableNotices' => when true, omits notices from being displayed
  70. * 'ignore' => a prefix for files and directories which are not being added
  71. * 'locale' => the actual set locale to use
  72. * 'log' => a instance of Zend_Log where logs are written to
  73. * 'logMessage' => message to be logged
  74. * 'logUntranslated' => when true, untranslated messages are not logged
  75. * 'reload' => reloads the cache by reading the content again
  76. * 'scan' => searches for translation files using the LOCALE constants
  77. *
  78. * @var array
  79. */
  80. protected $_options = array(
  81. 'clear' => false,
  82. 'content' => null,
  83. 'disableNotices' => false,
  84. 'ignore' => '.',
  85. 'locale' => 'auto',
  86. 'log' => null,
  87. 'logMessage' => "Untranslated message within '%locale%': %message%",
  88. 'logUntranslated' => false,
  89. 'reload' => false,
  90. 'route' => null,
  91. 'scan' => null
  92. );
  93. /**
  94. * Translation table
  95. * @var array
  96. */
  97. protected $_translate = array();
  98. /**
  99. * Generates the adapter
  100. *
  101. * @param array|Zend_Config $options Translation options for this adapter
  102. * @throws Zend_Translate_Exception
  103. * @return void
  104. */
  105. public function __construct($options = array())
  106. {
  107. if ($options instanceof Zend_Config) {
  108. $options = $options->toArray();
  109. } else if (func_num_args() > 1) {
  110. $args = func_get_args();
  111. $options = array();
  112. $options['content'] = array_shift($args);
  113. if (!empty($args)) {
  114. $options['locale'] = array_shift($args);
  115. }
  116. if (!empty($args)) {
  117. $opt = array_shift($args);
  118. $options = array_merge($opt, $options);
  119. }
  120. } else if (!is_array($options)) {
  121. $options = array('content' => $options);
  122. }
  123. if (array_key_exists('cache', $options)) {
  124. self::setCache($options['cache']);
  125. unset($options['cache']);
  126. }
  127. if (isset(self::$_cache)) {
  128. $id = 'Zend_Translate_' . $this->toString() . '_Options';
  129. $result = self::$_cache->load($id);
  130. if ($result) {
  131. $this->_options = $result;
  132. }
  133. }
  134. if (empty($options['locale']) || ($options['locale'] === "auto")) {
  135. $this->_automatic = true;
  136. } else {
  137. $this->_automatic = false;
  138. }
  139. $locale = null;
  140. if (!empty($options['locale'])) {
  141. $locale = $options['locale'];
  142. unset($options['locale']);
  143. }
  144. $this->setOptions($options);
  145. $options['locale'] = $locale;
  146. if (!empty($options['content'])) {
  147. $this->addTranslation($options);
  148. }
  149. if ($this->getLocale() !== (string) $options['locale']) {
  150. $this->setLocale($options['locale']);
  151. }
  152. }
  153. /**
  154. * Add translations
  155. *
  156. * This may be a new language or additional content for an existing language
  157. * If the key 'clear' is true, then translations for the specified
  158. * language will be replaced and added otherwise
  159. *
  160. * @param array|Zend_Config $options Options and translations to be added
  161. * @throws Zend_Translate_Exception
  162. * @return Zend_Translate_Adapter Provides fluent interface
  163. */
  164. public function addTranslation($options = array())
  165. {
  166. if ($options instanceof Zend_Config) {
  167. $options = $options->toArray();
  168. } else if (func_num_args() > 1) {
  169. $args = func_get_args();
  170. $options = array();
  171. $options['content'] = array_shift($args);
  172. if (!empty($args)) {
  173. $options['locale'] = array_shift($args);
  174. }
  175. if (!empty($args)) {
  176. $opt = array_shift($args);
  177. $options = array_merge($opt, $options);
  178. }
  179. } else if (!is_array($options)) {
  180. $options = array('content' => $options);
  181. }
  182. $originate = null;
  183. if (!empty($options['locale'])) {
  184. $originate = (string) $options['locale'];
  185. }
  186. if ((array_key_exists('log', $options)) && !($options['log'] instanceof Zend_Log)) {
  187. require_once 'Zend/Translate/Exception.php';
  188. throw new Zend_Translate_Exception('Instance of Zend_Log expected for option log');
  189. }
  190. try {
  191. if (!($options['content'] instanceof Zend_Translate) && !($options['content'] instanceof Zend_Translate_Adapter)) {
  192. if (empty($options['locale'])) {
  193. $options['locale'] = null;
  194. }
  195. $options['locale'] = Zend_Locale::findLocale($options['locale']);
  196. }
  197. } catch (Zend_Locale_Exception $e) {
  198. require_once 'Zend/Translate/Exception.php';
  199. throw new Zend_Translate_Exception("The given Language '{$options['locale']}' does not exist", 0, $e);
  200. }
  201. $options = $options + $this->_options;
  202. if (is_string($options['content']) and is_dir($options['content'])) {
  203. $options['content'] = realpath($options['content']);
  204. $prev = '';
  205. foreach (new RecursiveIteratorIterator(
  206. new RecursiveDirectoryIterator($options['content'], RecursiveDirectoryIterator::KEY_AS_PATHNAME),
  207. RecursiveIteratorIterator::SELF_FIRST) as $directory => $info) {
  208. $file = $info->getFilename();
  209. if (is_array($options['ignore'])) {
  210. foreach ($options['ignore'] as $key => $ignore) {
  211. if (strpos($key, 'regex') !== false) {
  212. if (preg_match($ignore, $directory)) {
  213. // ignore files matching the given regex from option 'ignore' and all files below
  214. continue 2;
  215. }
  216. } else if (strpos($directory, DIRECTORY_SEPARATOR . $ignore) !== false) {
  217. // ignore files matching first characters from option 'ignore' and all files below
  218. continue 2;
  219. }
  220. }
  221. } else {
  222. if (strpos($directory, DIRECTORY_SEPARATOR . $options['ignore']) !== false) {
  223. // ignore files matching first characters from option 'ignore' and all files below
  224. continue;
  225. }
  226. }
  227. if ($info->isDir()) {
  228. // pathname as locale
  229. if (($options['scan'] === self::LOCALE_DIRECTORY) and (Zend_Locale::isLocale($file, true, false))) {
  230. $options['locale'] = $file;
  231. $prev = (string) $options['locale'];
  232. }
  233. } else if ($info->isFile()) {
  234. // filename as locale
  235. if ($options['scan'] === self::LOCALE_FILENAME) {
  236. $filename = explode('.', $file);
  237. array_pop($filename);
  238. $filename = implode('.', $filename);
  239. if (Zend_Locale::isLocale((string) $filename, true, false)) {
  240. $options['locale'] = (string) $filename;
  241. } else {
  242. $parts = explode('.', $file);
  243. $parts2 = array();
  244. foreach($parts as $token) {
  245. $parts2 += explode('_', $token);
  246. }
  247. $parts = array_merge($parts, $parts2);
  248. $parts2 = array();
  249. foreach($parts as $token) {
  250. $parts2 += explode('-', $token);
  251. }
  252. $parts = array_merge($parts, $parts2);
  253. $parts = array_unique($parts);
  254. $prev = '';
  255. foreach($parts as $token) {
  256. if (Zend_Locale::isLocale($token, true, false)) {
  257. if (strlen($prev) <= strlen($token)) {
  258. $options['locale'] = $token;
  259. $prev = $token;
  260. }
  261. }
  262. }
  263. }
  264. }
  265. try {
  266. $options['content'] = $info->getPathname();
  267. $this->_addTranslationData($options);
  268. } catch (Zend_Translate_Exception $e) {
  269. // ignore failed sources while scanning
  270. }
  271. }
  272. }
  273. } else {
  274. $this->_addTranslationData($options);
  275. }
  276. if ((isset($this->_translate[$originate]) === true) and (count($this->_translate[$originate]) > 0)) {
  277. $this->setLocale($originate);
  278. }
  279. return $this;
  280. }
  281. /**
  282. * Sets new adapter options
  283. *
  284. * @param array $options Adapter options
  285. * @throws Zend_Translate_Exception
  286. * @return Zend_Translate_Adapter Provides fluent interface
  287. */
  288. public function setOptions(array $options = array())
  289. {
  290. $change = false;
  291. $locale = null;
  292. foreach ($options as $key => $option) {
  293. if ($key == 'locale') {
  294. $locale = $option;
  295. } else if ((isset($this->_options[$key]) and ($this->_options[$key] != $option)) or
  296. !isset($this->_options[$key])) {
  297. if (($key == 'log') && !($option instanceof Zend_Log)) {
  298. require_once 'Zend/Translate/Exception.php';
  299. throw new Zend_Translate_Exception('Instance of Zend_Log expected for option log');
  300. }
  301. if ($key == 'cache') {
  302. self::setCache($options);
  303. continue;
  304. }
  305. $this->_options[$key] = $option;
  306. $change = true;
  307. }
  308. }
  309. if ($locale !== null) {
  310. $this->setLocale($locale);
  311. }
  312. if (isset(self::$_cache) and ($change == true)) {
  313. $id = 'Zend_Translate_' . $this->toString() . '_Options';
  314. self::$_cache->save($this->_options, $id);
  315. }
  316. return $this;
  317. }
  318. /**
  319. * Returns the adapters name and it's options
  320. *
  321. * @param string|null $optionKey String returns this option
  322. * null returns all options
  323. * @return integer|string|array|null
  324. */
  325. public function getOptions($optionKey = null)
  326. {
  327. if ($optionKey === null) {
  328. return $this->_options;
  329. }
  330. if (isset($this->_options[$optionKey]) === true) {
  331. return $this->_options[$optionKey];
  332. }
  333. return null;
  334. }
  335. /**
  336. * Gets locale
  337. *
  338. * @return Zend_Locale|string|null
  339. */
  340. public function getLocale()
  341. {
  342. return $this->_options['locale'];
  343. }
  344. /**
  345. * Sets locale
  346. *
  347. * @param string|Zend_Locale $locale Locale to set
  348. * @throws Zend_Translate_Exception
  349. * @return Zend_Translate_Adapter Provides fluent interface
  350. */
  351. public function setLocale($locale)
  352. {
  353. if (($locale === "auto") or ($locale === null)) {
  354. $this->_automatic = true;
  355. } else {
  356. $this->_automatic = false;
  357. }
  358. try {
  359. $locale = Zend_Locale::findLocale($locale);
  360. } catch (Zend_Locale_Exception $e) {
  361. require_once 'Zend/Translate/Exception.php';
  362. throw new Zend_Translate_Exception("The given Language ({$locale}) does not exist", 0, $e);
  363. }
  364. if (!isset($this->_translate[$locale])) {
  365. $temp = explode('_', $locale);
  366. if (!isset($this->_translate[$temp[0]]) and !isset($this->_translate[$locale])) {
  367. if (!$this->_options['disableNotices']) {
  368. if ($this->_options['log']) {
  369. $this->_options['log']->notice("The language '{$locale}' has to be added before it can be used.");
  370. } else {
  371. trigger_error("The language '{$locale}' has to be added before it can be used.", E_USER_NOTICE);
  372. }
  373. }
  374. }
  375. $locale = $temp[0];
  376. }
  377. if (empty($this->_translate[$locale])) {
  378. if (!$this->_options['disableNotices']) {
  379. if ($this->_options['log']) {
  380. $this->_options['log']->notice("No translation for the language '{$locale}' available.");
  381. } else {
  382. trigger_error("No translation for the language '{$locale}' available.", E_USER_NOTICE);
  383. }
  384. }
  385. }
  386. if ($this->_options['locale'] != $locale) {
  387. $this->_options['locale'] = $locale;
  388. if (isset(self::$_cache)) {
  389. $id = 'Zend_Translate_' . $this->toString() . '_Options';
  390. self::$_cache->save($this->_options, $id);
  391. }
  392. }
  393. return $this;
  394. }
  395. /**
  396. * Returns the available languages from this adapter
  397. *
  398. * @return array
  399. */
  400. public function getList()
  401. {
  402. $list = array_keys($this->_translate);
  403. $result = null;
  404. foreach($list as $value) {
  405. if (!empty($this->_translate[$value])) {
  406. $result[$value] = $value;
  407. }
  408. }
  409. return $result;
  410. }
  411. /**
  412. * Returns the message id for a given translation
  413. * If no locale is given, the actual language will be used
  414. *
  415. * @param string $message Message to get the key for
  416. * @param string|Zend_Locale $locale (optional) Language to return the message ids from
  417. * @return string|array|false
  418. */
  419. public function getMessageId($message, $locale = null)
  420. {
  421. if (empty($locale) or !$this->isAvailable($locale)) {
  422. $locale = $this->_options['locale'];
  423. }
  424. return array_search($message, $this->_translate[(string) $locale]);
  425. }
  426. /**
  427. * Returns all available message ids from this adapter
  428. * If no locale is given, the actual language will be used
  429. *
  430. * @param string|Zend_Locale $locale (optional) Language to return the message ids from
  431. * @return array
  432. */
  433. public function getMessageIds($locale = null)
  434. {
  435. if (empty($locale) or !$this->isAvailable($locale)) {
  436. $locale = $this->_options['locale'];
  437. }
  438. return array_keys($this->_translate[(string) $locale]);
  439. }
  440. /**
  441. * Returns all available translations from this adapter
  442. * If no locale is given, the actual language will be used
  443. * If 'all' is given the complete translation dictionary will be returned
  444. *
  445. * @param string|Zend_Locale $locale (optional) Language to return the messages from
  446. * @return array
  447. */
  448. public function getMessages($locale = null)
  449. {
  450. if ($locale === 'all') {
  451. return $this->_translate;
  452. }
  453. if ((empty($locale) === true) or ($this->isAvailable($locale) === false)) {
  454. $locale = $this->_options['locale'];
  455. }
  456. return $this->_translate[(string) $locale];
  457. }
  458. /**
  459. * Is the wished language available ?
  460. *
  461. * @see Zend_Locale
  462. * @param string|Zend_Locale $locale Language to search for, identical with locale identifier,
  463. * @see Zend_Locale for more information
  464. * @return boolean
  465. */
  466. public function isAvailable($locale)
  467. {
  468. $return = isset($this->_translate[(string) $locale]);
  469. return $return;
  470. }
  471. /**
  472. * Load translation data
  473. *
  474. * @param mixed $data
  475. * @param string|Zend_Locale $locale
  476. * @param array $options (optional)
  477. * @return array
  478. */
  479. abstract protected function _loadTranslationData($data, $locale, array $options = array());
  480. /**
  481. * Internal function for adding translation data
  482. *
  483. * This may be a new language or additional data for an existing language
  484. * If the options 'clear' is true, then the translation data for the specified
  485. * language is replaced and added otherwise
  486. *
  487. * @see Zend_Locale
  488. * @param array|Zend_Config $content Translation data to add
  489. * @throws Zend_Translate_Exception
  490. * @return Zend_Translate_Adapter Provides fluent interface
  491. */
  492. private function _addTranslationData($options = array())
  493. {
  494. if ($options instanceof Zend_Config) {
  495. $options = $options->toArray();
  496. } else if (func_num_args() > 1) {
  497. $args = func_get_args();
  498. $options['content'] = array_shift($args);
  499. if (!empty($args)) {
  500. $options['locale'] = array_shift($args);
  501. }
  502. if (!empty($args)) {
  503. $options += array_shift($args);
  504. }
  505. }
  506. if (($options['content'] instanceof Zend_Translate) || ($options['content'] instanceof Zend_Translate_Adapter)) {
  507. $options['usetranslateadapter'] = true;
  508. if (!empty($options['locale']) && ($options['locale'] !== 'auto')) {
  509. $options['content'] = $options['content']->getMessages($options['locale']);
  510. } else {
  511. $content = $options['content'];
  512. $locales = $content->getList();
  513. foreach ($locales as $locale) {
  514. $options['locale'] = $locale;
  515. $options['content'] = $content->getMessages($locale);
  516. $this->_addTranslationData($options);
  517. }
  518. return $this;
  519. }
  520. }
  521. try {
  522. $options['locale'] = Zend_Locale::findLocale($options['locale']);
  523. } catch (Zend_Locale_Exception $e) {
  524. require_once 'Zend/Translate/Exception.php';
  525. throw new Zend_Translate_Exception("The given Language '{$options['locale']}' does not exist", 0, $e);
  526. }
  527. if ($options['clear'] || !isset($this->_translate[$options['locale']])) {
  528. $this->_translate[$options['locale']] = array();
  529. }
  530. $read = true;
  531. if (isset(self::$_cache)) {
  532. $id = 'Zend_Translate_' . md5(serialize($options['content'])) . '_' . $this->toString();
  533. $temp = self::$_cache->load($id);
  534. if ($temp) {
  535. $read = false;
  536. }
  537. }
  538. if ($options['reload']) {
  539. $read = true;
  540. }
  541. if ($read) {
  542. if (!empty($options['usetranslateadapter'])) {
  543. $temp = array($options['locale'] => $options['content']);
  544. } else {
  545. $temp = $this->_loadTranslationData($options['content'], $options['locale'], $options);
  546. }
  547. }
  548. if (empty($temp)) {
  549. $temp = array();
  550. }
  551. $keys = array_keys($temp);
  552. foreach($keys as $key) {
  553. if (!isset($this->_translate[$key])) {
  554. $this->_translate[$key] = array();
  555. }
  556. if (array_key_exists($key, $temp) && is_array($temp[$key])) {
  557. $this->_translate[$key] = $temp[$key] + $this->_translate[$key];
  558. }
  559. }
  560. if ($this->_automatic === true) {
  561. $find = new Zend_Locale($options['locale']);
  562. $browser = $find->getEnvironment() + $find->getBrowser();
  563. arsort($browser);
  564. foreach($browser as $language => $quality) {
  565. if (isset($this->_translate[$language])) {
  566. $this->_options['locale'] = $language;
  567. break;
  568. }
  569. }
  570. }
  571. if (($read) and (isset(self::$_cache))) {
  572. $id = 'Zend_Translate_' . md5(serialize($options['content'])) . '_' . $this->toString();
  573. self::$_cache->save($temp, $id);
  574. }
  575. return $this;
  576. }
  577. /**
  578. * Translates the given string
  579. * returns the translation
  580. *
  581. * @see Zend_Locale
  582. * @param string|array $messageId Translation string, or Array for plural translations
  583. * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with
  584. * locale identifier, @see Zend_Locale for more information
  585. * @return string
  586. */
  587. public function translate($messageId, $locale = null)
  588. {
  589. if ($locale === null) {
  590. $locale = $this->_options['locale'];
  591. }
  592. $plural = null;
  593. if (is_array($messageId)) {
  594. if (count($messageId) > 2) {
  595. $number = array_pop($messageId);
  596. if (!is_numeric($number)) {
  597. $plocale = $number;
  598. $number = array_pop($messageId);
  599. } else {
  600. $plocale = 'en';
  601. }
  602. $plural = $messageId;
  603. $messageId = $messageId[0];
  604. } else {
  605. $messageId = $messageId[0];
  606. }
  607. }
  608. if (!Zend_Locale::isLocale($locale, true, false)) {
  609. if (!Zend_Locale::isLocale($locale, false, false)) {
  610. // language does not exist, return original string
  611. $this->_log($messageId, $locale);
  612. // use rerouting when enabled
  613. if (!empty($this->_options['route'])) {
  614. if (array_key_exists($locale, $this->_options['route']) &&
  615. !array_key_exists($locale, $this->_routed)) {
  616. $this->_routed[$locale] = true;
  617. return $this->translate($messageId, $this->_options['route'][$locale]);
  618. }
  619. }
  620. $this->_routed = array();
  621. if ($plural === null) {
  622. return $messageId;
  623. }
  624. $rule = Zend_Translate_Plural::getPlural($number, $plocale);
  625. if (!isset($plural[$rule])) {
  626. $rule = 0;
  627. }
  628. return $plural[$rule];
  629. }
  630. $locale = new Zend_Locale($locale);
  631. }
  632. $locale = (string) $locale;
  633. if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) {
  634. // return original translation
  635. if ($plural === null) {
  636. $this->_routed = array();
  637. return $this->_translate[$locale][$messageId];
  638. }
  639. $rule = Zend_Translate_Plural::getPlural($number, $locale);
  640. if (isset($this->_translate[$locale][$plural[0]][$rule])) {
  641. $this->_routed = array();
  642. return $this->_translate[$locale][$plural[0]][$rule];
  643. }
  644. } else if (strlen($locale) != 2) {
  645. // faster than creating a new locale and separate the leading part
  646. $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
  647. if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) {
  648. // return regionless translation (en_US -> en)
  649. if ($plural === null) {
  650. $this->_routed = array();
  651. return $this->_translate[$locale][$messageId];
  652. }
  653. $rule = Zend_Translate_Plural::getPlural($number, $locale);
  654. if (isset($this->_translate[$locale][$plural[0]][$rule])) {
  655. $this->_routed = array();
  656. return $this->_translate[$locale][$plural[0]][$rule];
  657. }
  658. }
  659. }
  660. $this->_log($messageId, $locale);
  661. // use rerouting when enabled
  662. if (!empty($this->_options['route'])) {
  663. if (array_key_exists($locale, $this->_options['route']) &&
  664. !array_key_exists($locale, $this->_routed)) {
  665. $this->_routed[$locale] = true;
  666. return $this->translate($messageId, $this->_options['route'][$locale]);
  667. }
  668. }
  669. $this->_routed = array();
  670. if ($plural === null) {
  671. return $messageId;
  672. }
  673. $rule = Zend_Translate_Plural::getPlural($number, $plocale);
  674. if (!isset($plural[$rule])) {
  675. $rule = 0;
  676. }
  677. return $plural[$rule];
  678. }
  679. /**
  680. * Translates the given string using plural notations
  681. * Returns the translated string
  682. *
  683. * @see Zend_Locale
  684. * @param string $singular Singular translation string
  685. * @param string $plural Plural translation string
  686. * @param integer $number Number for detecting the correct plural
  687. * @param string|Zend_Locale $locale (Optional) Locale/Language to use, identical with
  688. * locale identifier, @see Zend_Locale for more information
  689. * @return string
  690. */
  691. public function plural($singular, $plural, $number, $locale = null)
  692. {
  693. return $this->translate(array($singular, $plural, $number), $locale);
  694. }
  695. /**
  696. * Logs a message when the log option is set
  697. *
  698. * @param string $message Message to log
  699. * @param String $locale Locale to log
  700. */
  701. protected function _log($message, $locale) {
  702. if ($this->_options['logUntranslated']) {
  703. $message = str_replace('%message%', $message, $this->_options['logMessage']);
  704. $message = str_replace('%locale%', $locale, $message);
  705. if ($this->_options['log']) {
  706. $this->_options['log']->notice($message);
  707. } else {
  708. trigger_error($message, E_USER_NOTICE);
  709. }
  710. }
  711. }
  712. /**
  713. * Translates the given string
  714. * returns the translation
  715. *
  716. * @param string $messageId Translation string
  717. * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with locale
  718. * identifier, @see Zend_Locale for more information
  719. * @return string
  720. */
  721. public function _($messageId, $locale = null)
  722. {
  723. return $this->translate($messageId, $locale);
  724. }
  725. /**
  726. * Checks if a string is translated within the source or not
  727. * returns boolean
  728. *
  729. * @param string $messageId Translation string
  730. * @param boolean $original (optional) Allow translation only for original language
  731. * when true, a translation for 'en_US' would give false when it can
  732. * be translated with 'en' only
  733. * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with locale identifier,
  734. * see Zend_Locale for more information
  735. * @return boolean
  736. */
  737. public function isTranslated($messageId, $original = false, $locale = null)
  738. {
  739. if (($original !== false) and ($original !== true)) {
  740. $locale = $original;
  741. $original = false;
  742. }
  743. if ($locale === null) {
  744. $locale = $this->_options['locale'];
  745. }
  746. if (!Zend_Locale::isLocale($locale, true, false)) {
  747. if (!Zend_Locale::isLocale($locale, false, false)) {
  748. // language does not exist, return original string
  749. return false;
  750. }
  751. $locale = new Zend_Locale($locale);
  752. }
  753. $locale = (string) $locale;
  754. if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) {
  755. // return original translation
  756. return true;
  757. } else if ((strlen($locale) != 2) and ($original === false)) {
  758. // faster than creating a new locale and separate the leading part
  759. $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
  760. if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) {
  761. // return regionless translation (en_US -> en)
  762. return true;
  763. }
  764. }
  765. // No translation found, return original
  766. return false;
  767. }
  768. /**
  769. * Returns the set cache
  770. *
  771. * @return Zend_Cache_Core The set cache
  772. */
  773. public static function getCache()
  774. {
  775. return self::$_cache;
  776. }
  777. /**
  778. * Sets a cache for all Zend_Translate_Adapters
  779. *
  780. * @param Zend_Cache_Core $cache Cache to store to
  781. */
  782. public static function setCache(Zend_Cache_Core $cache)
  783. {
  784. self::$_cache = $cache;
  785. }
  786. /**
  787. * Returns true when a cache is set
  788. *
  789. * @return boolean
  790. */
  791. public static function hasCache()
  792. {
  793. if (self::$_cache !== null) {
  794. return true;
  795. }
  796. return false;
  797. }
  798. /**
  799. * Removes any set cache
  800. *
  801. * @return void
  802. */
  803. public static function removeCache()
  804. {
  805. self::$_cache = null;
  806. }
  807. /**
  808. * Clears all set cache data
  809. *
  810. * @return void
  811. */
  812. public static function clearCache()
  813. {
  814. require_once 'Zend/Cache.php';
  815. self::$_cache->clean(Zend_Cache::CLEANING_MODE_ALL);
  816. }
  817. /**
  818. * Returns the adapter name
  819. *
  820. * @return string
  821. */
  822. abstract public function toString();
  823. }