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