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 |
require_once('php-mo.php'); |
22 |
|
23 |
// languages for home |
24 |
$langs = array( |
25 |
'ast' => 'Asturianu', |
26 |
'ca' => 'Català', |
27 |
'cs' => 'Čeština', |
28 |
'de' => 'Deutsch', |
29 |
'el' => 'Ελληνικά', |
30 |
'en' => 'English', |
31 |
'eo' => 'Esperanto', |
32 |
'es' => 'Español', |
33 |
'et' => 'Eesti', |
34 |
'fi' => 'Suomeksi', |
35 |
'fr' => 'Français', |
36 |
'id' => 'Bahasa Indonesia', |
37 |
'it' => 'Italiano', |
38 |
'lv' => 'Latviešu', |
39 |
'nb' => 'Bokmål', |
40 |
'nl' => 'Nederlands', |
41 |
'pl' => 'Polski', |
42 |
'pt' => 'Português', |
43 |
'pt-br' => 'Português do Brasil', |
44 |
'ro' => 'Română', |
45 |
'ru' => 'Русский', |
46 |
'sl' => 'Slovenščina', |
47 |
'sq' => 'Gjuha shqipe', |
48 |
'sv' => 'Svenska', |
49 |
'tr' => 'Türkçe', |
50 |
'uk' => 'Українська', |
51 |
'ur' => 'اردو', |
52 |
'zh-cn' => '简体中文', |
53 |
'zh-tw' => '正體中文' |
54 |
); |
55 |
|
56 |
class NCache |
57 |
{ |
58 |
function __construct() { } |
59 |
|
60 |
/** |
61 |
* Factory. |
62 |
* |
63 |
* @param string $path where cache file store is located, relative to app path. |
64 |
* @param integer $timeout in seconds |
65 |
* |
66 |
* @return NCache |
67 |
*/ |
68 |
public static function build($path, $timeout = 3600) |
69 |
{ |
70 |
$path = __DIR__ . '/' . $path; |
71 |
|
72 |
if (!is_dir($path)) |
73 |
return null; |
74 |
|
75 |
if ($timeout < 60) |
76 |
$timeout = 60; |
77 |
|
78 |
$i = new self; |
79 |
$i->_path = $path; |
80 |
$i->_timeout = $timeout; |
81 |
|
82 |
return $i; |
83 |
} |
84 |
|
85 |
/** |
86 |
* Get value for $key. |
87 |
* |
88 |
* @param mixed $key |
89 |
* |
90 |
* @return mixed |
91 |
*/ |
92 |
function get($key = null) |
93 |
{ |
94 |
if (is_null($key)) |
95 |
return false; |
96 |
|
97 |
$filename = $this->_get_filename($key); |
98 |
|
99 |
if ($this->_is_valid_file($filename, $this->_timeout)) { |
100 |
return unserialize(file_get_contents($filename)); |
101 |
} |
102 |
|
103 |
return null; |
104 |
} |
105 |
|
106 |
/** |
107 |
* Save $value under $key. |
108 |
* |
109 |
* @param mixed $key |
110 |
* @param mixed $value |
111 |
*/ |
112 |
function set($key, $value) |
113 |
{ |
114 |
if (is_null($key)) |
115 |
return false; |
116 |
|
117 |
$filename = $this->_get_filename($key); |
118 |
file_put_contents($filename, serialize($value)); |
119 |
|
120 |
return true; |
121 |
} |
122 |
|
123 |
/** |
124 |
* Get cache file from key. |
125 |
* |
126 |
* @param mixed $key |
127 |
* |
128 |
* @return string |
129 |
*/ |
130 |
private function _get_filename($key) |
131 |
{ |
132 |
$key = hash('sha1', serialize($key)); |
133 |
|
134 |
return $this->_path . '/' . $key . '.cache'; |
135 |
} |
136 |
|
137 |
/** |
138 |
* Check that the cache file exists and has not expired. |
139 |
* |
140 |
* @param string $filename |
141 |
* |
142 |
* @return boolean |
143 |
*/ |
144 |
private function _is_valid_file($filename, $timeout) |
145 |
{ |
146 |
if (!file_exists($filename)) { |
147 |
//error_log(sprintf('Could not find %s', $filename), 0); |
148 |
return false; |
149 |
} |
150 |
|
151 |
if (filemtime($filename) + $timeout < time()) { |
152 |
//error_log(sprintf('%s timestamp expired (timeout was %ds.).', $filename, $timeout)); |
153 |
unlink($filename); |
154 |
return false; |
155 |
} |
156 |
|
157 |
//error_log(sprintf('Found %s', $filename)); |
158 |
return true; |
159 |
} |
160 |
} |
161 |
|
162 |
class l10n |
163 |
{ |
164 |
// public static $t; |
165 |
|
166 |
/** |
167 |
* Load langs/$lang.lang into global $_t array. |
168 |
* |
169 |
* @param string $lang |
170 |
* |
171 |
* @return void |
172 |
*/ |
173 |
public static function load($lang) |
174 |
{ |
175 |
global $_t; |
176 |
$_t = array(); |
177 |
|
178 |
if ($lang == 'en') |
179 |
return; |
180 |
|
181 |
$po_file = __DIR__ . '/langs/' . $lang . '.po'; |
182 |
$cache_file = __DIR__ . '/var/tmp/cache/nav_lang_' . $lang . '.php'; |
183 |
$po_ts = filemtime($po_file); |
184 |
|
185 |
if (file_exists($cache_file)) { |
186 |
include $cache_file; |
187 |
if ($_ts > $po_ts) |
188 |
return; |
189 |
} |
190 |
|
191 |
if (file_exists($po_file)) { |
192 |
$dictionary = phpmo_parse_po_file($po_file); |
193 |
|
194 |
foreach ($dictionary as $key => $value) { |
195 |
if ($key != '') { |
196 |
if ($value['msgstr'][0] != '') { |
197 |
$_t[trim($key)] = trim($value['msgstr'][0]); |
198 |
} else { |
199 |
$_t[trim($key)] = trim($key); |
200 |
} |
201 |
} |
202 |
} |
203 |
|
204 |
$_t_data = var_export($_t, true); |
205 |
$cache = <<<P |
206 |
<?php |
207 |
/**! Generated. Do not edit. */ |
208 |
|
209 |
// filemtime($po_file) |
210 |
\$_ts = $po_ts; |
211 |
|
212 |
// $lang strings |
213 |
global \$_t; |
214 |
\$_t = $_t_data; |
215 |
P; |
216 |
file_put_contents($cache_file, $cache); |
217 |
} |
218 |
} |
219 |
|
220 |
/** |
221 |
* Get value for key $s in global array $_t. |
222 |
* |
223 |
* @param string $s |
224 |
* |
225 |
* @return string |
226 |
*/ |
227 |
public static function _t($s) { |
228 |
if (trim($s) == '') |
229 |
return ''; |
230 |
|
231 |
global $_t; |
232 |
|
233 |
$s = array_key_exists($s, $_t) ? $_t[$s] : $s; |
234 |
$s = trim(str_replace(array('{ok}', '{OK}', '{Ok}', '{oK}'), '', $s)); |
235 |
|
236 |
return $s; |
237 |
} |
238 |
} |
239 |
|
240 |
/** |
241 |
* Produce navigation HTML code. |
242 |
* |
243 |
* @param boolean $wrap = false should it be wrapped in a <header id="nav" /> element? |
244 |
* @param string $lang = 'en' |
245 |
* @param string $inject = null |
246 |
* @param string $vhost = 'www.mageia.org' |
247 |
* @param object $cache |
248 |
* |
249 |
* @return string HTML code |
250 |
*/ |
251 |
function _mgnav_html($wrap = false, $lang = 'en', $inject = null, $vhost = 'www.mageia.org', $cache = null) |
252 |
{ |
253 |
$key = array($wrap, $lang, $inject, $vhost); |
254 |
|
255 |
if (!is_null($cache) && ($h = $cache->get($key))) { |
256 |
apache_note('navCacheHit', 1); |
257 |
return $h; |
258 |
} |
259 |
|
260 |
apache_note('navCacheHit', 0); |
261 |
|
262 |
$lang = _lang_check($lang); |
263 |
|
264 |
l10n::load($lang, $cache); |
265 |
|
266 |
$tn = array( |
267 |
array('mageia', '//$S/$L/map/', 'Mageia', l10n::_t('Go to mageia.org site map.')), |
268 |
array('about', '//$S/$L/about/', l10n::_t('About us'), l10n::_t('Learn more about Mageia.')), |
269 |
array('downloads', '//$S/$L/downloads/', l10n::_t('Downloads'), l10n::_t('Download Mageia ISO and updates.')), |
270 |
array('support', '//$S/$L/support/', l10n::_t('Support'), l10n::_t('Get support from Mageia community.')), |
271 |
array('wiki', '//wiki.mageia.org/', l10n::_t('Wiki'), l10n::_t('Wiki of the Mageia Community')), |
272 |
array('doc', '//$S/$L/doc/', l10n::_t('Docs'), l10n::_t('Documentations of Mageia')), |
273 |
array('community', '//$S/$L/community/', l10n::_t('Community'), l10n::_t('')), |
274 |
array('contribute', '//$S/$L/contribute/', l10n::_t('Contribute'), l10n::_t('You too can build Mageia with us!')), |
275 |
array('donate', '//$S/$L/donate/', l10n::_t('Donate'), l10n::_t('')), |
276 |
array('you', '//identity.mageia.org/', l10n::_t('You'), l10n::_t('Your Mageia online account.')), |
277 |
array('contact', '//$S/$L/contact/', l10n::_t('Contact'), l10n::_t('Contact Us')) |
278 |
// <search> |
279 |
); |
280 |
|
281 |
$s = array(); |
282 |
foreach ($tn as $i) { |
283 |
$s[] = sprintf('<li><a href="%s" class="%s" title="%s">%s</a></li>', |
284 |
str_replace( |
285 |
array('$L', '$S'), |
286 |
array($lang, $vhost), |
287 |
$i[1] |
288 |
), |
289 |
$i[0], |
290 |
$i[3], |
291 |
$i[2] |
292 |
); |
293 |
} |
294 |
|
295 |
if (!is_null($inject)) |
296 |
$s[] = sprintf('<li>%s</li>', $inject); |
297 |
|
298 |
$s = implode($s); |
299 |
$h = sprintf('<!--googleoff: all--><nav id="mgnav"><ul id="nav">%s</ul></nav><!--googleon: all-->', $s); |
300 |
|
301 |
if ($wrap) |
302 |
$h = sprintf('<header id="hmgn">%s |
303 |
<link rel="icon" type="image/png" href="/g/favicon.png" /> |
304 |
</header>', $h); |
305 |
|
306 |
if (!is_null($cache)) |
307 |
$cache->set($key, $h); |
308 |
|
309 |
return $h; |
310 |
} |
311 |
|
312 |
/** |
313 |
* Returns CSS definition ready to be inserted into a HTML document. |
314 |
* |
315 |
* @return string |
316 |
*/ |
317 |
function _mgnav_style() |
318 |
{ |
319 |
if ( defined('ALIGNMENT') && constant('ALIGNMENT') == 'Center' ){ |
320 |
return '<style>' . file_get_contents(__DIR__ . '/css/source.css') . '</style><style>' . file_get_contents(__DIR__ . '/css/center.css') . '</style>'; |
321 |
} else { |
322 |
return '<style>' . file_get_contents(__DIR__ . '/css/source.css') . '</style>'; |
323 |
} |
324 |
} |
325 |
|
326 |
/** |
327 |
* Get the primary language subtag only.<p></p> |
328 |
*/ |
329 |
function _lang_check($s = null) |
330 |
{ |
331 |
if (is_null($s)) { |
332 |
return 'en'; |
333 |
} |
334 |
|
335 |
global $langs; |
336 |
$supported = array_keys($langs); |
337 |
|
338 |
if (in_array($s, $supported)) |
339 |
return $s; |
340 |
|
341 |
$sub = explode('-', $s); |
342 |
$sub = strtolower($sub[0]); |
343 |
|
344 |
if (in_array($sub, $supported)) |
345 |
return $sub; |
346 |
|
347 |
return 'en'; |
348 |
} |