1: <?php namespace Laravel;
2:
3: class Lang {
4:
5: /**
6: * The key of the language line being retrieved.
7: *
8: * @var string
9: */
10: protected $key;
11:
12: /**
13: * The replacements that should be made on the language line.
14: *
15: * @var array
16: */
17: protected $replacements;
18:
19: /**
20: * The language in which the line should be retrieved.
21: *
22: * @var string
23: */
24: protected $language;
25:
26: /**
27: * All of the loaded language lines.
28: *
29: * The array is keyed by [$bundle][$language][$file].
30: *
31: * @var array
32: */
33: protected static $lines = array();
34:
35: /**
36: * The language loader event name.
37: *
38: * @var string
39: */
40: const loader = 'laravel.language.loader';
41:
42: /**
43: * Create a new Lang instance.
44: *
45: * @param string $key
46: * @param array $replacements
47: * @param string $language
48: * @return void
49: */
50: protected function __construct($key, $replacements = array(), $language = null)
51: {
52: $this->key = $key;
53: $this->language = $language;
54: $this->replacements = (array) $replacements;
55: }
56:
57: /**
58: * Create a new language line instance.
59: *
60: * <code>
61: * // Create a new language line instance for a given line
62: * $line = Lang::line('validation.required');
63: *
64: * // Create a new language line for a line belonging to a bundle
65: * $line = Lang::line('admin::messages.welcome');
66: *
67: * // Specify some replacements for the language line
68: * $line = Lang::line('validation.required', array('attribute' => 'email'));
69: * </code>
70: *
71: * @param string $key
72: * @param array $replacements
73: * @param string $language
74: * @return Lang
75: */
76: public static function line($key, $replacements = array(), $language = null)
77: {
78: if (is_null($language)) $language = Config::get('application.language');
79:
80: return new static($key, $replacements, $language);
81: }
82:
83: /**
84: * Determine if a language line exists.
85: *
86: * @param string $key
87: * @param string $language
88: * @return bool
89: */
90: public static function has($key, $language = null)
91: {
92: return static::line($key, array(), $language)->get() !== $key;
93: }
94:
95: /**
96: * Get the language line as a string.
97: *
98: * <code>
99: * // Get a language line
100: * $line = Lang::line('validation.required')->get();
101: *
102: * // Get a language line in a specified language
103: * $line = Lang::line('validation.required')->get('sp');
104: *
105: * // Return a default value if the line doesn't exist
106: * $line = Lang::line('validation.required')->get(null, 'Default');
107: * </code>
108: *
109: * @param string $language
110: * @param string $default
111: * @return string
112: */
113: public function get($language = null, $default = null)
114: {
115: // If no default value is specified by the developer, we'll just return the
116: // key of the language line. This should indicate which language line we
117: // were attempting to render and is better than giving nothing back.
118: if (is_null($default)) $default = $this->key;
119:
120: if (is_null($language)) $language = $this->language;
121:
122: list($bundle, $file, $line) = $this->parse($this->key);
123:
124: // If the file does not exist, we'll just return the default value that was
125: // given to the method. The default value is also returned even when the
126: // file exists and that file does not actually contain any lines.
127: if ( ! static::load($bundle, $language, $file))
128: {
129: return value($default);
130: }
131:
132: $lines = static::$lines[$bundle][$language][$file];
133:
134: $line = array_get($lines, $line, $default);
135:
136: // If the line is not a string, it probably means the developer asked for
137: // the entire language file and the value of the requested value will be
138: // an array containing all of the lines in the file.
139: if (is_string($line))
140: {
141: foreach ($this->replacements as $key => $value)
142: {
143: $line = str_replace(':'.$key, $value, $line);
144: }
145: }
146:
147: return $line;
148: }
149:
150: /**
151: * Parse a language key into its bundle, file, and line segments.
152: *
153: * Language lines follow a {bundle}::{file}.{line} naming convention.
154: *
155: * @param string $key
156: * @return array
157: */
158: protected function parse($key)
159: {
160: $bundle = Bundle::name($key);
161:
162: $segments = explode('.', Bundle::element($key));
163:
164: // If there are not at least two segments in the array, it means that
165: // the developer is requesting the entire language line array to be
166: // returned. If that is the case, we'll make the item "null".
167: if (count($segments) >= 2)
168: {
169: $line = implode('.', array_slice($segments, 1));
170:
171: return array($bundle, $segments[0], $line);
172: }
173: else
174: {
175: return array($bundle, $segments[0], null);
176: }
177: }
178:
179: /**
180: * Load all of the language lines from a language file.
181: *
182: * @param string $bundle
183: * @param string $language
184: * @param string $file
185: * @return bool
186: */
187: public static function load($bundle, $language, $file)
188: {
189: if (isset(static::$lines[$bundle][$language][$file]))
190: {
191: return true;
192: }
193:
194: // We use a "loader" event to delegate the loading of the language
195: // array, which allows the develop to organize the language line
196: // arrays for their application however they wish.
197: $lines = Event::first(static::loader, func_get_args());
198:
199: static::$lines[$bundle][$language][$file] = $lines;
200:
201: return count($lines) > 0;
202: }
203:
204: /**
205: * Load a language array from a language file.
206: *
207: * @param string $bundle
208: * @param string $language
209: * @param string $file
210: * @return array
211: */
212: public static function file($bundle, $language, $file)
213: {
214: $lines = array();
215:
216: // Language files can belongs to the application or to any bundle
217: // that is installed for the application. So, we'll need to use
218: // the bundle's path when looking for the file.
219: $path = static::path($bundle, $language, $file);
220:
221: if (file_exists($path))
222: {
223: $lines = require $path;
224: }
225:
226: return $lines;
227: }
228:
229: /**
230: * Get the path to a bundle's language file.
231: *
232: * @param string $bundle
233: * @param string $language
234: * @param string $file
235: * @return string
236: */
237: protected static function path($bundle, $language, $file)
238: {
239: return Bundle::path($bundle)."language/{$language}/{$file}".EXT;
240: }
241:
242: /**
243: * Get the string content of the language line.
244: *
245: * @return string
246: */
247: public function __toString()
248: {
249: return (string) $this->get();
250: }
251:
252: }
253: