file.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <?php
  2. namespace Fuel\Core;
  3. /**
  4. * A base Lang File class for File based configs.
  5. */
  6. abstract class Lang_File implements Lang_Interface
  7. {
  8. protected $file;
  9. protected $languages = array();
  10. protected $vars = array();
  11. /**
  12. * Sets up the file to be parsed and variables
  13. *
  14. * @param string $file Lang file name
  15. * @param array $languages Languages to scan for the lang file
  16. * @param array $vars Variables to parse in the file
  17. * @return void
  18. */
  19. public function __construct($file = null, $languages = array(), $vars = array())
  20. {
  21. $this->file = $file;
  22. $this->languages = $languages;
  23. $this->vars = array(
  24. 'APPPATH' => APPPATH,
  25. 'COREPATH' => COREPATH,
  26. 'PKGPATH' => PKGPATH,
  27. 'DOCROOT' => DOCROOT,
  28. ) + $vars;
  29. }
  30. /**
  31. * Loads the language file(s).
  32. *
  33. * @param bool $overwrite Whether to overwrite existing values
  34. * @return array the language array
  35. */
  36. public function load($overwrite = false)
  37. {
  38. $paths = $this->find_file();
  39. $lang = array();
  40. foreach ($paths as $path)
  41. {
  42. $lang = $overwrite ?
  43. array_merge($lang, $this->load_file($path)) :
  44. \Arr::merge($lang, $this->load_file($path));
  45. }
  46. return $lang;
  47. }
  48. /**
  49. * Gets the default group name.
  50. *
  51. * @return string
  52. */
  53. public function group()
  54. {
  55. return $this->file;
  56. }
  57. /**
  58. * Parses a string using all of the previously set variables. Allows you to
  59. * use something like %APPPATH% in non-PHP files.
  60. *
  61. * @param string $string String to parse
  62. * @return string
  63. */
  64. protected function parse_vars($string)
  65. {
  66. foreach ($this->vars as $var => $val)
  67. {
  68. $string = str_replace("%$var%", $val, $string);
  69. }
  70. return $string;
  71. }
  72. /**
  73. * Replaces FuelPHP's path constants to their string counterparts.
  74. *
  75. * @param array $array array to be prepped
  76. * @return array prepped array
  77. */
  78. protected function prep_vars(&$array)
  79. {
  80. static $replacements = false;
  81. if ($replacements === false)
  82. {
  83. foreach ($this->vars as $i => $v)
  84. {
  85. $replacements['#^('.preg_quote($v).'){1}(.*)?#'] = "%".$i."%$2";
  86. }
  87. }
  88. foreach ($array as $i => $value)
  89. {
  90. if (is_string($value))
  91. {
  92. $array[$i] = preg_replace(array_keys($replacements), array_values($replacements), $value);
  93. }
  94. elseif(is_array($value))
  95. {
  96. $this->prep_vars($array[$i]);
  97. }
  98. }
  99. }
  100. /**
  101. * Finds the given language files
  102. *
  103. * @param bool $multiple Whether to load multiple files or not
  104. * @return array
  105. */
  106. protected function find_file()
  107. {
  108. $paths = array();
  109. foreach ($this->languages as $lang)
  110. {
  111. $paths = array_merge($paths, \Finder::search('lang'.DS.$lang, $this->file, $this->ext, true));
  112. }
  113. if (count($paths) > 0)
  114. {
  115. return array_reverse($paths);
  116. }
  117. throw new \LangException(sprintf('File "%s" does not exist.', $this->file));
  118. }
  119. /**
  120. * Formats the output and saved it to disc.
  121. *
  122. * @param string $identifier filename
  123. * @param $contents $contents language array to save
  124. * @return bool \File::update result
  125. */
  126. public function save($identifier, $contents)
  127. {
  128. // get the formatted output
  129. $output = $this->export_format($contents);
  130. if ( ! $output)
  131. {
  132. return false;
  133. }
  134. if ( ! $path = \Finder::search('lang', $identifier))
  135. {
  136. if ($pos = strripos($identifier, '::'))
  137. {
  138. // get the namespace path
  139. if ($path = \Autoloader::namespace_path('\\'.ucfirst(substr($identifier, 0, $pos))))
  140. {
  141. // strip the namespace from the filename
  142. $identifier = substr($identifier, $pos+2);
  143. // strip the classes directory as we need the module root
  144. $path = substr($path,0, -8).'lang'.DS.$identifier;
  145. }
  146. else
  147. {
  148. // invalid namespace requested
  149. return false;
  150. }
  151. }
  152. }
  153. // absolute path requested?
  154. if ($identifier[0] === '/' or (isset($identifier[1]) and $identifier[1] === ':'))
  155. {
  156. $path = $identifier;
  157. }
  158. // make sure we have a fallback
  159. $path or $path = APPPATH.'lang'.DS.$identifier;
  160. $path = pathinfo($path);
  161. if ( ! is_dir($path['dirname']))
  162. {
  163. mkdir($path['dirname'], 0777, true);
  164. }
  165. return \File::update($path['dirname'], $path['basename'], $output);
  166. }
  167. /**
  168. * Must be implemented by child class. Gets called for each file to load.
  169. */
  170. abstract protected function load_file($file);
  171. /**
  172. * Must be impletmented by child class. Gets called when saving a language file.
  173. *
  174. * @param array $contents language array to save
  175. * @return string formatted output
  176. */
  177. abstract protected function export_format($contents);
  178. }