PageRenderTime 26ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/tmx.class.php

https://github.com/Stormfaint/TMX-Reader---Writer
PHP | 301 lines | 174 code | 20 blank | 107 comment | 51 complexity | 2734f5b07fc51de4068c330e43a9dc33 MD5 | raw file
  1. <?php
  2. /**
  3. * Reader et Writer de fichiers de TMX en PHP
  4. *
  5. * La classe permet de lire, de modifier et créer un fichier de traduction au format TMX en PHP
  6. *
  7. * @author Maxime Maupeu <maxime.maupeu@gmail.com>
  8. * @version 1.0
  9. * @since 1.0
  10. * @link https://github.com/Stormfaint
  11. */
  12. class Tmx{
  13. /**
  14. * Nom du fichier TMX
  15. *
  16. * @var string
  17. */
  18. private $_file = null;
  19. /**
  20. * Traductions extraites de fichier TMX
  21. *
  22. * @var array
  23. */
  24. private $_data = array();
  25. /**
  26. * Contexte : fichier existant ou non (création)
  27. *
  28. * @var boolean
  29. */
  30. private $_creation = false;
  31. /**
  32. * Mode debug (retour d'exceptions)
  33. *
  34. * @var boolean
  35. */
  36. private $_debug = false;
  37. /**
  38. * Version par défaut d'XML utilisée
  39. */
  40. const DOCUMENT = '1.0';
  41. /**
  42. * Version par défaut de TMX utilisé
  43. */
  44. const VERSION = '1.4';
  45. /**
  46. * Encodage par défaut du fichier
  47. */
  48. const ENCODAGE = 'UTF-8';
  49. /**
  50. * Sauvegarde d'un backup du fichier avant modification
  51. */
  52. const BACKUP = true;
  53. /**
  54. * Sauvegarde réalisée à chaque modification à l'aide d'un timestamp
  55. */
  56. const MULTIBACKUP = false;
  57. /**
  58. * Constructeur
  59. *
  60. * @param string $file
  61. * @param boolean $create
  62. * @param null|string $encodage
  63. * @param boolean $debug
  64. * @throws Exception si l'extension libxml n'est pas activée dans PHP, nécessaire pour XMLReader et XMLWriter
  65. * @throws Exception si le fichier n'est accessible en écriture
  66. * @throws Exception si le répertoire lors de la création d'un fichier n'est pas accessible en écriture
  67. * @throws Exception si le fichier n'existe pas
  68. * @return boolean
  69. */
  70. public function __construct($file, $create = false, $encodage = null, $debug = false){
  71. $this->_debug = $debug;
  72. if(!class_exists('XMLReader') || !class_exists('XMLWriter')){
  73. if($this->_debug)
  74. throw new Exception('PHP extension libxml is required : http://www.php.net/manual/fr/book.libxml.php');
  75. else return false;
  76. }
  77. if(file_exists($file)){
  78. if(!is_readable($file)){
  79. if($this->_debug)
  80. throw new Exception('File exist but not readable.');
  81. return false;
  82. }
  83. $this->_file = $file;
  84. $this->read($encodage);
  85. }elseif($create){
  86. if(!$parent = trim(substr_replace($file . ' ', '', strripos($file, '/'), -1))){
  87. $parent = dirname(__FILE__);
  88. }
  89. if(!is_writable($parent)){
  90. if($this->_debug)
  91. throw new Exception('Directory exist but not writable.');
  92. return false;
  93. }
  94. @fopen($file, 'w');
  95. @chmod($this->_file, 0755);
  96. $this->_file = $file;
  97. $this->_creation = true;
  98. }else{
  99. if($this->_debug)
  100. throw new Exception('File not exist.');
  101. return false;
  102. }
  103. return true;
  104. }
  105. /**
  106. * Méthode permettant de lire le fichier et charger les traductions
  107. *
  108. * @param null|string $encodage
  109. * @throws Exception si le fichier n'existe pas
  110. * @return Tmx
  111. */
  112. private function read($encodage = null){
  113. if($encodage === null) $encodage = self::ENCODAGE;
  114. if($this->_file === null){
  115. if($this->_debug)
  116. throw new Exception('No file.');
  117. else return false;
  118. }
  119. $reader = new XMLReader();
  120. $reader->open($this->_file, $encodage);
  121. while($reader->read()){
  122. if($reader->nodeType == XMLReader::ELEMENT){
  123. switch($reader->localName){
  124. case 'tu': $tuid = $reader->getAttribute('tuid'); break;
  125. case 'tuv': $xmlLang = $reader->xmlLang; break;
  126. case 'seg':
  127. if($reader->read()){
  128. if(
  129. ($reader->nodeType == XMLReader::TEXT || $reader->nodeType == XMLReader::CDATA)
  130. && $tuid && $xmlLang
  131. ){
  132. $this->_data[$tuid][$xmlLang] = $reader->value;
  133. }
  134. }
  135. break;
  136. }
  137. }
  138. }
  139. $reader->close();
  140. return $this;
  141. }
  142. /**
  143. * Méthode d'écrire dans un fichier TMX et de l'enregistrer
  144. *
  145. * @param null|string $encodage
  146. * @throws Exception si le fichier n'existe pas
  147. * @return Tmx
  148. */
  149. public function write($encodage = null){
  150. if($this->_file === null){
  151. if($this->_debug)
  152. throw new Exception('No file.');
  153. else return false;
  154. }
  155. if($encodage === null) $encodage = self::ENCODAGE;
  156. $writer = new XMLWriter();
  157. $writer->openMemory();
  158. $writer->startDocument(self::DOCUMENT, $encodage);
  159. $writer->startElement('tmx');
  160. $writer->writeAttribute('version', self::VERSION);
  161. $writer->setIndentString("\t");
  162. $writer->setIndent(true);
  163. $writer->startElement('body');
  164. foreach($this->_data as $tuid => $tuvs){
  165. $writer->startElement('tu');
  166. $writer->writeAttribute('tuid', $tuid);
  167. foreach($tuvs as $xmlLang => $value){
  168. $writer->startElement('tuv');
  169. $writer->writeAttribute('xml:lang', $xmlLang);
  170. $writer->writeElement('seg', $value);
  171. $writer->endElement();
  172. }
  173. $writer->endElement();
  174. }
  175. $writer->endElement();
  176. $writer->endElement();
  177. $writer->endDocument();
  178. if(self::BACKUP && $this->_creation === false){
  179. $copy = $this->_file . '.bak';
  180. if(self::MULTIBACKUP) $copy .= '.' . time();
  181. @copy($this->_file, $copy);
  182. }
  183. $file = @fopen($this->_file, 'w');
  184. @fwrite($file, $writer->outputMemory(true));
  185. return $this;
  186. }
  187. /**
  188. * Méthode permettant d'ajouter une traduction
  189. *
  190. * @param string $tuid
  191. * @param string $xmlLang
  192. * @param string $value
  193. * @return Tmx
  194. */
  195. public function set($tuid, $xmlLang = false, $value = false){
  196. if(is_array($tuid)) return $this->setArray($tuid);
  197. if($xmlLang != false && $value != false) $this->_data[$tuid][$xmlLang] = $value;
  198. return $this;
  199. }
  200. /**
  201. * Méthode permettant d'ajouter une ou plusieurs traductions à l'aide d'un tableau
  202. *
  203. * @param array $data
  204. * @return Tmx
  205. */
  206. public function setArray(array $data){
  207. foreach($data as $_data){
  208. if(is_array($_data)){
  209. if(count($_data) > 2){
  210. $this->set($_data[0], $_data[1], $_data[2]);
  211. }
  212. }
  213. }
  214. return $this;
  215. }
  216. /**
  217. * Méthode permettant de supprimer une traduction
  218. *
  219. * @param string $tuid
  220. * @param string $xmlLang
  221. * @return Tmx
  222. */
  223. public function delete($tuid, $xmlLang = false){
  224. if($xmlLang){
  225. if(isset($this->_data[$tuid]) && isset($this->_data[$tuid][$xmlLang])){
  226. unset($this->_data[$tuid][$xmlLang]);
  227. if(empty($this->_data[$tuid])){
  228. unset($this->_data[$tuid]);
  229. }
  230. }
  231. }else{
  232. if(isset($this->_data[$tuid])){
  233. unset($this->_data[$tuid]);
  234. }
  235. }
  236. return $this;
  237. }
  238. /**
  239. * Méthode permettant de récupérer les traductions d'un fichier préalablement chargé,
  240. * selon un identifiant, un identifiant et une langue, ou l'ensemble d'un fichier
  241. *
  242. * @param boolean|string $tuid
  243. * @param boolean|string $xmlLang
  244. * @return boolean|string|array
  245. */
  246. public function get($tuid = false, $xmlLang = false){
  247. if($xmlLang && $tuid){
  248. if(array_key_exists($tuid, $this->_data)){
  249. if(array_key_exists($xmlLang, $this->_data[$tuid])){
  250. return $this->_data[$tuid][$xmlLang];
  251. }
  252. return false;
  253. }
  254. return false;
  255. }
  256. if($tuid){
  257. if(array_key_exists($tuid, $this->_data)){
  258. return $this->_data[$tuid];
  259. }
  260. return false;
  261. }
  262. return $this->_data;
  263. }
  264. /**
  265. * Méthode permettant de récupérer l'ensemble des traductions en une langue donnée
  266. *
  267. * @param string $xmlLang
  268. * @return array
  269. */
  270. public function getLang($xmlLang){
  271. $data = $this->_data;
  272. foreach($data as $_tuid => $_data){
  273. foreach($_data as $_xmlLang => $_value){
  274. if($_xmlLang != $xmlLang){
  275. unset($data[$_tuid][$_xmlLang]);
  276. }
  277. }
  278. }
  279. return $data;
  280. }
  281. }