1 |
<?php |
2 |
// definition |
3 |
|
4 |
class NCache |
5 |
{ |
6 |
function __construct() { } |
7 |
|
8 |
/** |
9 |
* Factory. |
10 |
* |
11 |
* @param string $path where cache file store is located, relative to app path. |
12 |
* @param integer $timeout in seconds |
13 |
* |
14 |
* @return NCache |
15 |
*/ |
16 |
function build($path, $timeout = 3600) |
17 |
{ |
18 |
$path = __DIR__ . '/' . $path; |
19 |
|
20 |
if (!is_dir($path)) |
21 |
return null; |
22 |
|
23 |
if ($timeout < 60) |
24 |
$timeout = 60; |
25 |
|
26 |
$i = new self; |
27 |
$i->_path = $path; |
28 |
$i->_timeout = $timeout; |
29 |
|
30 |
return $i; |
31 |
} |
32 |
|
33 |
/** |
34 |
* Get value for $key. |
35 |
* |
36 |
* @param mixed $key |
37 |
* |
38 |
* @return mixed |
39 |
*/ |
40 |
function get($key = null) |
41 |
{ |
42 |
if (is_null($key)) |
43 |
return false; |
44 |
|
45 |
$filename = $this->_get_filename($key); |
46 |
|
47 |
if ($this->_is_valid_file($filename, $this->_timeout)) { |
48 |
return unserialize(file_get_contents($filename)); |
49 |
} |
50 |
|
51 |
return null; |
52 |
} |
53 |
|
54 |
/** |
55 |
* Save $value under $key. |
56 |
* |
57 |
* @param mixed $key |
58 |
* @param mixed $value |
59 |
*/ |
60 |
function set($key, $value) |
61 |
{ |
62 |
if (is_null($key)) |
63 |
return false; |
64 |
|
65 |
$filename = $this->_get_filename($key); |
66 |
file_put_contents($filename, serialize($value)); |
67 |
|
68 |
return true; |
69 |
} |
70 |
|
71 |
/** |
72 |
* Get cache file from key. |
73 |
* |
74 |
* @param mixed $key |
75 |
* |
76 |
* @return string |
77 |
*/ |
78 |
private function _get_filename($key) |
79 |
{ |
80 |
$key = hash('sha1', serialize($key)); |
81 |
|
82 |
return $this->_path . '/' . $key . '.cache'; |
83 |
} |
84 |
|
85 |
/** |
86 |
* Check that the cache file exists and has not expired. |
87 |
* |
88 |
* @param string $filename |
89 |
* |
90 |
* @return boolean |
91 |
*/ |
92 |
private function _is_valid_file($filename, $timeout) |
93 |
{ |
94 |
if (!file_exists($filename)) { |
95 |
//error_log(sprintf('Could not find %s', $filename), 0); |
96 |
return false; |
97 |
} |
98 |
|
99 |
if (filemtime($filename) + $timeout < time()) { |
100 |
//error_log(sprintf('%s timestamp expired (timeout was %ds.).', $filename, $timeout)); |
101 |
unlink($filename); |
102 |
return false; |
103 |
} |
104 |
|
105 |
//error_log(sprintf('Found %s', $filename)); |
106 |
return true; |
107 |
} |
108 |
} |
109 |
|
110 |
class l10n |
111 |
{ |
112 |
public static $t; |
113 |
|
114 |
/** |
115 |
* Load langs/$lang.lang into global $_t array. |
116 |
* |
117 |
* @param string $lang |
118 |
* |
119 |
* @return void |
120 |
*/ |
121 |
function load($lang) |
122 |
{ |
123 |
global $_t; |
124 |
$_t = array(); |
125 |
|
126 |
if ($lang == 'en') |
127 |
return; |
128 |
|
129 |
$lang_file = __DIR__ . '/langs/' . $lang . '.lang'; |
130 |
$cache_file = __DIR__ . '/var/tmp/cache/nav_lang_' . $lang . '.php'; |
131 |
$lang_ts = filemtime($lang_file); |
132 |
|
133 |
if (file_exists($cache_file)) { |
134 |
include $cache_file; |
135 |
if ($_ts > $lang_ts) |
136 |
return; |
137 |
} |
138 |
|
139 |
if (file_exists($lang_file)) { |
140 |
|
141 |
$f = file($lang_file); |
142 |
|
143 |
foreach ($f as $k => $v) { |
144 |
|
145 |
if (substr($v, 0, 1) == ';' |
146 |
&& !empty($f[$k+1])) |
147 |
{ |
148 |
$_t[trim(substr($v, 1))] = trim($f[$k+1]); |
149 |
} |
150 |
} |
151 |
|
152 |
// |
153 |
$_t_data = var_export($_t, true); |
154 |
$cache = <<<P |
155 |
<?php |
156 |
/**! Generated. Do not edit. */ |
157 |
|
158 |
// filemtime($lang_file) |
159 |
\$_ts = $lang_ts; |
160 |
|
161 |
// $lang strings |
162 |
global \$_t; |
163 |
\$_t = $_t_data; |
164 |
P; |
165 |
file_put_contents($cache_file, $cache); |
166 |
} |
167 |
} |
168 |
|
169 |
/** |
170 |
* Get value for key $s in global array $_t. |
171 |
* |
172 |
* @param string $s |
173 |
* |
174 |
* @return string |
175 |
*/ |
176 |
function _t($s) { |
177 |
if (trim($s) == '') |
178 |
return ''; |
179 |
|
180 |
global $_t; |
181 |
|
182 |
return array_key_exists($s, $_t) ? $_t[$s] : $s; |
183 |
} |
184 |
} |
185 |
|
186 |
/** |
187 |
* Produce navigation HTML code. |
188 |
* |
189 |
* @param boolean $wrap = false should it be wrapped in a <header id="nav" /> element? |
190 |
* @param string $lang = 'en' |
191 |
* @param string $inject = null |
192 |
* @param string $vhost = 'www.mageia.org' |
193 |
* @param object $cache |
194 |
* |
195 |
* @return string HTML code |
196 |
*/ |
197 |
function _mgnav_html($wrap = false, $lang = 'en', $inject = null, $vhost = 'www.mageia.org', $cache = null) |
198 |
{ |
199 |
$key = array($wrap, $lang, $inject, $vhost); |
200 |
|
201 |
if (!is_null($cache) && ($h = $cache->get($key))) { |
202 |
apache_note('navCacheHit', 1); |
203 |
return $h; |
204 |
} |
205 |
|
206 |
apache_note('navCacheHit', 0); |
207 |
|
208 |
$lang = _lang_check($lang); |
209 |
|
210 |
l10n::load($lang, $cache); |
211 |
|
212 |
$tn = array( |
213 |
array('mageia', '//$S/$L/map/', 'Mageia', l10n::_t('Go to mageia.org site map.')), |
214 |
array('about', '//$S/$L/about/', l10n::_t('About us'), l10n::_t('Learn more about Mageia.')), |
215 |
array('downloads', '//$S/$L/downloads/', l10n::_t('Downloads'), l10n::_t('Download Mageia ISO and updates.')), |
216 |
array('support', '//$S/$L/support/', l10n::_t('Support'), l10n::_t('Get support from Mageia community.')), |
217 |
array('community', '//$S/$L/community/', l10n::_t('Community'), l10n::_t('')), |
218 |
array('contribute', '//$S/$L/contribute/', l10n::_t('Contribute'), l10n::_t('You too can build Mageia with us!')), |
219 |
array('you', '//identity.mageia.org/', l10n::_t('You'), l10n::_t('Your Mageia online account.')), |
220 |
array('contact', '//$S/$L/contact/', l10n::_t('Contact'), l10n::_t('Contact Us')) |
221 |
// <search> |
222 |
); |
223 |
|
224 |
$s = array(); |
225 |
foreach ($tn as $i) { |
226 |
$s[] = sprintf('<li><a href="%s" class="%s" title="%s">%s</a></li>', |
227 |
str_replace( |
228 |
array('$L', '$S'), |
229 |
array($lang, $vhost), |
230 |
$i[1] |
231 |
), |
232 |
$i[0], |
233 |
$i[3], |
234 |
$i[2] |
235 |
); |
236 |
} |
237 |
|
238 |
if (!is_null($inject)) |
239 |
$s[] = sprintf('<li>%s</li>', $inject); |
240 |
|
241 |
$s = implode($s); |
242 |
$h = sprintf('<!--googleoff: all--><nav id="mgnav"><ul id="nav">%s</ul></nav><!--googleon: all-->', $s); |
243 |
|
244 |
if ($wrap) |
245 |
$h = sprintf('<header id="hmgn">%s</header>', $h); |
246 |
|
247 |
if (!is_null($cache)) |
248 |
$cache->set($key, $h); |
249 |
|
250 |
return $h; |
251 |
} |
252 |
|
253 |
/** |
254 |
* Returns CSS definition ready to be inserted into a HTML document. |
255 |
* |
256 |
* @return string |
257 |
*/ |
258 |
function _mgnav_style() |
259 |
{ |
260 |
return '<style>' . file_get_contents(__DIR__ . '/css/source.css') . '</style>'; |
261 |
} |
262 |
|
263 |
/** |
264 |
* Get the primary language subtag only.<p></p> |
265 |
*/ |
266 |
function _lang_check($s = null) |
267 |
{ |
268 |
if (is_null($s)) { |
269 |
return 'en'; |
270 |
} |
271 |
|
272 |
$supported = array( |
273 |
'cs', |
274 |
'de', |
275 |
'el', 'en', 'eo', 'es', 'et', |
276 |
'fi', 'fr', |
277 |
'id', 'it', |
278 |
'lv', |
279 |
'nb', 'nl', |
280 |
'pl', 'pt', 'pt-br', |
281 |
'ro', 'ru', |
282 |
'sl', |
283 |
'tr', |
284 |
'uk', |
285 |
'zh-cn', 'zh-tw' |
286 |
); |
287 |
|
288 |
if (in_array($s, $supported)) |
289 |
return $s; |
290 |
|
291 |
$sub = explode('-', $s); |
292 |
$sub = strtolower($sub[0]); |
293 |
|
294 |
if (in_array($sub, $supported)) |
295 |
return $sub; |
296 |
|
297 |
return 'en'; |
298 |
} |