r4776 bugfix: LivePorts MAC address lister was broken with Huawei S5300 V100R006
[racktables-incomplete-works] / wwwroot / inc / interface-lib.php
CommitLineData
ca8aa8e9
DO
1<?php
2
d3535346
DO
3define ('TAGNAME_REGEXP', '/^[\p{L}0-9]([. _~-]?[\p{L}0-9])*$/u');
4define ('AUTOTAGNAME_REGEXP', '/^\$[\p{L}0-9]([. _~-]?[\p{L}0-9])*$/u');
5
ca8aa8e9
DO
6// Let's have it here, so extensions can add their own images.
7$image = array();
ca8aa8e9
DO
8$image['rackspace']['path'] = 'pix/racks.png';
9$image['rackspace']['width'] = 218;
10$image['rackspace']['height'] = 200;
11$image['objects']['path'] = 'pix/server.png';
12$image['objects']['width'] = 218;
13$image['objects']['height'] = 200;
14$image['depot']['path'] = 'pix/server.png';
15$image['depot']['width'] = 218;
16$image['depot']['height'] = 200;
17$image['files']['path'] = 'pix/files.png';
18$image['files']['width'] = 218;
19$image['files']['height'] = 200;
20$image['ipv4space']['path'] = 'pix/addressspace.png';
21$image['ipv4space']['width'] = 218;
22$image['ipv4space']['height'] = 200;
23$image['ipv6space']['path'] = 'pix/addressspacev6.png';
24$image['ipv6space']['width'] = 218;
25$image['ipv6space']['height'] = 200;
26$image['ipv4slb']['path'] = 'pix/slb.png';
27$image['ipv4slb']['width'] = 218;
28$image['ipv4slb']['height'] = 200;
29$image['config']['path'] = 'pix/configuration.png';
30$image['config']['width'] = 218;
31$image['config']['height'] = 200;
32$image['reports']['path'] = 'pix/report.png';
33$image['reports']['width'] = 218;
34$image['reports']['height'] = 200;
35$image['8021q']['path'] = 'pix/8021q.png';
36$image['8021q']['width'] = 218;
37$image['8021q']['height'] = 200;
38$image['objectlog']['path'] = 'pix/crystal-mimetypes-shellscript-218x200.png';
39$image['objectlog']['width'] = 218;
40$image['objectlog']['height'] = 200;
41$image['virtual']['path'] = 'pix/virtualresources.png';
42$image['virtual']['width'] = 218;
43$image['virtual']['height'] = 200;
44$image['download']['path'] = 'pix/download.png';
45$image['download']['width'] = 16;
46$image['download']['height'] = 16;
47$image['DOWNLOAD']['path'] = 'pix/download-big.png';
48$image['DOWNLOAD']['width'] = 32;
49$image['DOWNLOAD']['height'] = 32;
50$image['plug']['path'] = 'pix/tango-network-wired.png';
51$image['plug']['width'] = 16;
52$image['plug']['height'] = 16;
53$image['cut']['path'] = 'pix/tango-edit-cut-16x16.png';
54$image['cut']['width'] = 16;
55$image['cut']['height'] = 16;
56$image['Cut']['path'] = 'pix/tango-edit-cut-22x22.png';
57$image['Cut']['width'] = 22;
58$image['Cut']['height'] = 22;
75a01117
DO
59$image['Cut gray']['path'] = 'pix/tango-edit-cut-22x22-gray.png';
60$image['Cut gray']['width'] = 22;
61$image['Cut gray']['height'] = 22;
ca8aa8e9
DO
62$image['CUT']['path'] = 'pix/tango-edit-cut-32x32.png';
63$image['CUT']['width'] = 32;
64$image['CUT']['height'] = 32;
65$image['add']['path'] = 'pix/tango-list-add.png';
66$image['add']['width'] = 16;
67$image['add']['height'] = 16;
68$image['ADD']['path'] = 'pix/tango-list-add-big.png';
69$image['ADD']['width'] = 32;
70$image['ADD']['height'] = 32;
71$image['delete']['path'] = 'pix/tango-list-remove.png';
72$image['delete']['width'] = 16;
73$image['delete']['height'] = 16;
74$image['DELETE']['path'] = 'pix/tango-list-remove-32x32.png';
75$image['DELETE']['width'] = 32;
76$image['DELETE']['height'] = 32;
77$image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
78$image['destroy']['width'] = 16;
79$image['destroy']['height'] = 16;
80$image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
81$image['nodestroy']['width'] = 16;
82$image['nodestroy']['height'] = 16;
83$image['NODESTROY']['path'] = 'pix/tango-user-trash-32x32-gray.png';
84$image['NODESTROY']['width'] = 32;
85$image['NODESTROY']['height'] = 32;
86$image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
87$image['DESTROY']['width'] = 32;
88$image['DESTROY']['height'] = 32;
89$image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
90$image['nodelete']['width'] = 16;
91$image['nodelete']['height'] = 16;
92$image['inservice']['path'] = 'pix/tango-emblem-system.png';
93$image['inservice']['width'] = 16;
94$image['inservice']['height'] = 16;
95$image['notinservice']['path'] = 'pix/tango-dialog-error.png';
96$image['notinservice']['width'] = 16;
97$image['notinservice']['height'] = 16;
98$image['find']['path'] = 'pix/tango-system-search.png';
99$image['find']['width'] = 16;
100$image['find']['height'] = 16;
101$image['next']['path'] = 'pix/tango-go-next.png';
102$image['next']['width'] = 32;
103$image['next']['height'] = 32;
104$image['prev']['path'] = 'pix/tango-go-previous.png';
105$image['prev']['width'] = 32;
106$image['prev']['height'] = 32;
107$image['COMMIT']['path'] = 'pix/tango-go-prev-next-32x32.png';
108$image['COMMIT']['width'] = 32;
109$image['COMMIT']['height'] = 32;
110$image['COMMIT gray']['path'] = 'pix/tango-go-prev-next-gray-32x32.png';
111$image['COMMIT gray']['width'] = 32;
112$image['COMMIT gray']['height'] = 32;
113$image['RECALC']['path'] = 'pix/tango-view-refresh-32x32.png';
114$image['RECALC']['width'] = 32;
115$image['RECALC']['height'] = 32;
116$image['clear']['path'] = 'pix/tango-edit-clear.png';
117$image['clear']['width'] = 16;
118$image['clear']['height'] = 16;
119$image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
120$image['CLEAR']['width'] = 32;
121$image['CLEAR']['height'] = 32;
122$image['CLEAR gray']['path'] = 'pix/tango-edit-clear-gray-32x32.png';
123$image['CLEAR gray']['width'] = 32;
124$image['CLEAR gray']['height'] = 32;
125$image['save']['path'] = 'pix/tango-document-save-16x16.png';
126$image['save']['width'] = 16;
127$image['save']['height'] = 16;
128$image['SAVE']['path'] = 'pix/tango-document-save-32x32.png';
129$image['SAVE']['width'] = 32;
130$image['SAVE']['height'] = 32;
131$image['NOSAVE']['path'] = 'pix/tango-document-save-32x32-gray.png';
132$image['NOSAVE']['width'] = 32;
133$image['NOSAVE']['height'] = 32;
134$image['create']['path'] = 'pix/tango-document-new.png';
135$image['create']['width'] = 16;
136$image['create']['height'] = 16;
137$image['CREATE']['path'] = 'pix/tango-document-new-big.png';
138$image['CREATE']['width'] = 32;
139$image['CREATE']['height'] = 32;
140$image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
141$image['DENIED']['width'] = 32;
142$image['DENIED']['height'] = 32;
143$image['node-collapsed']['path'] = 'pix/node-collapsed.png';
144$image['node-collapsed']['width'] = 16;
145$image['node-collapsed']['height'] = 16;
146$image['node-expanded']['path'] = 'pix/node-expanded.png';
147$image['node-expanded']['width'] = 16;
148$image['node-expanded']['height'] = 16;
149$image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
150$image['node-expanded-static']['width'] = 16;
151$image['node-expanded-static']['height'] = 16;
152$image['dragons']['path'] = 'pix/mitsudragon.png';
153$image['dragons']['width'] = 195;
154$image['dragons']['height'] = 33;
155$image['LB']['path'] = 'pix/loadbalancer.png';
156$image['LB']['width'] = 32;
157$image['LB']['height'] = 32;
158$image['RS pool']['path'] = 'pix/serverpool.png';
159$image['RS pool']['width'] = 48;
160$image['RS pool']['height'] = 16;
161$image['VS']['path'] = 'pix/servicesign.png';
162$image['VS']['width'] = 39;
163$image['VS']['height'] = 62;
164$image['router']['path'] = 'pix/router.png';
165$image['router']['width'] = 32;
166$image['router']['height'] = 32;
167$image['object']['path'] = 'pix/bracket-16x16.png';
168$image['object']['width'] = 16;
169$image['object']['height'] = 16;
170$image['OBJECT']['path'] = 'pix/bracket-32x32.png';
171$image['OBJECT']['width'] = 32;
172$image['OBJECT']['height'] = 32;
173$image['attach']['path'] = 'pix/tango-mail-attachment-16x16.png';
174$image['attach']['width'] = 16;
175$image['attach']['height'] = 16;
176$image['Attach']['path'] = 'pix/tango-mail-attachment-22x22.png';
177$image['Attach']['width'] = 22;
178$image['Attach']['height'] = 22;
179$image['ATTACH']['path'] = 'pix/tango-mail-attachment-32x32.png';
180$image['ATTACH']['width'] = 32;
181$image['ATTACH']['height'] = 32;
182$image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
183$image['favorite']['width'] = 16;
184$image['favorite']['height'] = 16;
185$image['computer']['path'] = 'pix/tango-computer.png';
186$image['computer']['width'] = 16;
187$image['computer']['height'] = 16;
188$image['empty file']['path'] = 'pix/crystal-file-empty-32x32.png';
189$image['empty file']['width'] = 32;
190$image['empty file']['height'] = 32;
191$image['text file']['path'] = 'pix/crystal-file-text-32x32.png';
192$image['text file']['width'] = 32;
193$image['text file']['height'] = 32;
194$image['image file']['path'] = 'pix/crystal-file-image-32x32.png';
195$image['image file']['width'] = 32;
196$image['image file']['height'] = 32;
197$image['text']['path'] = 'pix/tango-text-x-generic-16x16.png';
198$image['text']['width'] = 16;
199$image['text']['height'] = 16;
200$image['NET']['path'] = 'pix/crystal-network_local-32x32.png';
201$image['NET']['width'] = 32;
202$image['NET']['height'] = 32;
203$image['net']['path'] = 'pix/crystal-network_local-16x16.png';
204$image['net']['width'] = 16;
205$image['net']['height'] = 16;
206$image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
207$image['USER']['width'] = 32;
208$image['USER']['height'] = 32;
209$image['setfilter']['path'] = 'pix/pgadmin3-viewfiltereddata.png';
210$image['setfilter']['width'] = 32;
211$image['setfilter']['height'] = 32;
212$image['setfilter gray']['path'] = 'pix/pgadmin3-viewfiltereddata-grayscale.png';
213$image['setfilter gray']['width'] = 32;
214$image['setfilter gray']['height'] = 32;
215$image['resetfilter']['path'] = 'pix/pgadmin3-viewdata.png';
216$image['resetfilter']['width'] = 32;
217$image['resetfilter']['height'] = 32;
218$image['resetfilter gray']['path'] = 'pix/pgadmin3-viewdata-grayscale.png';
219$image['resetfilter gray']['width'] = 32;
220$image['resetfilter gray']['height'] = 32;
221$image['knight']['path'] = 'pix/smiley_knight.png';
222$image['knight']['width'] = 72;
223$image['knight']['height'] = 33;
224$image['Zoom']['path'] = 'pix/tango-system-search-22x22.png';
225$image['Zoom']['width'] = 22;
226$image['Zoom']['height'] = 22;
227$image['Zooming']['path'] = 'pix/tango-view-fullscreen-22x22.png';
228$image['Zooming']['width'] = 22;
229$image['Zooming']['height'] = 22;
230$image['UNLOCK']['path'] = 'pix/crystal-actions-unlock-32x32.png';
231$image['UNLOCK']['width'] = 32;
232$image['UNLOCK']['height'] = 32;
233$image['CLOCK']['path'] = 'pix/tango-appointment-32x32.png';
234$image['CLOCK']['width'] = 32;
235$image['CLOCK']['height'] = 32;
236$image['DQUEUE done']['path'] = 'pix/crystal-ok-32x32.png';
237$image['DQUEUE done']['width'] = 32;
238$image['DQUEUE done']['height'] = 32;
239$image['DQUEUE sync_aging']['path'] = 'pix/tango-appointment-32x32.png';
240$image['DQUEUE sync_aging']['width'] = 32;
241$image['DQUEUE sync_aging']['height'] = 32;
242$image['DQUEUE resync_aging']['path'] = 'pix/tango-appointment-32x32.png';
243$image['DQUEUE resync_aging']['width'] = 32;
244$image['DQUEUE resync_aging']['height'] = 32;
245$image['DQUEUE sync_ready']['path'] = 'pix/tango-emblem-system-32x32.png';
246$image['DQUEUE sync_ready']['width'] = 32;
247$image['DQUEUE sync_ready']['height'] = 32;
248$image['DQUEUE resync_ready']['path'] = 'pix/tango-emblem-important-32x32.png';
249$image['DQUEUE resync_ready']['width'] = 32;
250$image['DQUEUE resync_ready']['height'] = 32;
251$image['DQUEUE failed']['path'] = 'pix/tango-emblem-unreadable-32x32.png';
252$image['DQUEUE failed']['width'] = 32;
253$image['DQUEUE failed']['height'] = 32;
254$image['DQUEUE disabled']['path'] = 'pix/tango-emblem-readonly-32x32.png';
255$image['DQUEUE disabled']['width'] = 32;
256$image['DQUEUE disabled']['height'] = 32;
257$image['COPY']['path'] = 'pix/tango-edit-copy-32x32.png';
258$image['COPY']['width'] = 32;
259$image['COPY']['height'] = 32;
260$image['html']['path'] = 'pix/tango-text-html.png';
261$image['html']['width'] = 16;
262$image['html']['height'] = 16;
263
264function printSelect ($optionList, $select_attrs = array(), $selected_id = NULL)
265{
266 echo getSelect ($optionList, $select_attrs, $selected_id);
267}
268
269// Input array keys are OPTION VALUEs and input array values are OPTION text.
c4ad9ac0 270function getSelect ($optionList, $select_attrs = array(), $selected_id = NULL, $treat_single_special = TRUE)
ca8aa8e9
DO
271{
272 $ret = '';
273 if (!array_key_exists ('name', $select_attrs))
274 return '';
275 // handle two corner cases in a specific way
276 if (count ($optionList) == 0)
277 return '(none)';
c4ad9ac0 278 if (count ($optionList) == 1 && $treat_single_special)
ca8aa8e9
DO
279 {
280 foreach ($optionList as $key => $value) { break; }
281 return "<input type=hidden name=${select_attrs['name']} id=${select_attrs['name']} value=${key}>" . $value;
282 }
283 if (!array_key_exists ('id', $select_attrs))
284 $select_attrs['id'] = $select_attrs['name'];
285 $ret .= '<select';
286 foreach ($select_attrs as $attr_name => $attr_value)
287 $ret .= " ${attr_name}=${attr_value}";
288 $ret .= '>';
289 foreach ($optionList as $dict_key => $dict_value)
290 $ret .= "<option value='${dict_key}'" . ($dict_key == $selected_id ? ' selected' : '') . ">${dict_value}</option>";
291 $ret .= '</select>';
292 return $ret;
293}
294
295function printNiftySelect ($groupList, $select_attrs = array(), $selected_id = NULL, $autocomplete = false)
296{
297 echo getNiftySelect ($groupList, $select_attrs, $selected_id);
298}
299
300// Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
301// format as printSelect() expects.
7232ef01
AD
302// If tree is true, hierarchical drop-boxes are used, otherwise optgroups are used.
303function getNiftySelect ($groupList, $select_attrs, $selected_id = NULL, $tree = false)
ca8aa8e9
DO
304{
305 // special treatment for ungrouped data
306 if (count ($groupList) == 1 and isset ($groupList['other']))
307 return getSelect ($groupList['other'], $select_attrs, $selected_id);
308 if (!array_key_exists ('name', $select_attrs))
309 return '';
310 if (!array_key_exists ('id', $select_attrs))
311 $select_attrs['id'] = $select_attrs['name'];
7232ef01 312 if ($tree)
ca8aa8e9 313 {
2f06f6be
DO
314 # it is safe to call many times for the same file
315 addJS ('js/jquery.optionTree.js');
7232ef01
AD
316 $ret = "<input type=hidden name=${select_attrs['name']}>\n";
317 $ret .= "<script type='text/javascript'>\n";
318 $ret .= "\$(function() {\n";
319 $ret .= " var option_tree = {\n";
320 foreach ($groupList as $groupname => $groupdata)
321 {
322 $ret .= " '${groupname}': {";
323 foreach ($groupdata as $dict_key => $dict_value)
324 $ret .= "\"${dict_value}\":'${dict_key}', ";
325 $ret .= "},\n";
326 }
327 $ret .= " };\n";
30dce055 328 $ret .= " var options = {empty_value: '', choose: 'select...'};\n";
7232ef01
AD
329 $ret .= " \$('input[name=${select_attrs['name']}]').optionTree(option_tree, options);\n";
330 $ret .= "});\n";
331 $ret .= "</script>\n";
332 }
333 else
334 {
335 $ret = '<select';
336 foreach ($select_attrs as $attr_name => $attr_value)
337 $ret .= " ${attr_name}=${attr_value}";
338 $ret .= ">\n";
339 foreach ($groupList as $groupname => $groupdata)
340 {
341 $ret .= "<optgroup label='${groupname}'>\n";
342 foreach ($groupdata as $dict_key => $dict_value)
343 $ret .= "<option value='${dict_key}'" . ($dict_key == $selected_id ? ' selected' : '') . ">${dict_value}</option>\n";
344 $ret .= "</optgroup>\n";
345 }
346 $ret .= "</select>\n";
ca8aa8e9 347 }
ca8aa8e9
DO
348 return $ret;
349}
350
16d86b28
DO
351function getOptionTree ($tree_name, $tree_options, $tree_config = array())
352{
77b5137a
DO
353 function serializeJSArray ($options)
354 {
355 $tmp = array();
356 foreach ($options as $key => $value)
357 $tmp[] = "'${key}': \"${value}\"";
358 return '{' . implode (', ', $tmp) . "}\n";
359 }
360 function serializeJSTree ($tree_options)
16d86b28
DO
361 {
362 $self = __FUNCTION__;
363 $tmp = array();
77b5137a
DO
364 # Leaves on the PHP tree are stored "value => label" way,
365 # non-leaves are stored "label => array" way, and the JS
366 # tree is always built "label => value" or "label => array"
367 # way, hence a structure transform is required.
368 foreach ($tree_options as $key => $value)
369 $tmp[] = is_array ($value) ?
370 "\"${key}\": " . $self ($value) :
f6adcafc 371 "\"${value}\": \"${key}\"";
16d86b28
DO
372 return '{' . implode (', ', $tmp) . "}\n";
373 }
374
375 $default_config = array
376 (
377 'choose' => 'select...',
378 'empty_value' => '',
379 );
380 foreach ($tree_config as $cfgoption_name => $cfgoption_value)
381 $default_config[$cfgoption_name] = $cfgoption_value;
382 # it is safe to call many times for the same file
383 addJS ('js/jquery.optionTree.js');
384 $ret = "<input type=hidden name=${tree_name}>\n";
385 $ret .= "<script type='text/javascript'>\n";
386 $ret .= "\$(function() {\n";
77b5137a 387 $ret .= " var option_tree = " . serializeJSTree ($tree_options) . ";\n";
16d86b28
DO
388 $ret .= " var options = " . serializeJSArray ($default_config) . ";\n";
389 $ret .= " \$('input[name=${tree_name}]').optionTree(option_tree, options);\n";
390 $ret .= "});\n";
391 $ret .= "</script>\n";
392 return $ret;
393}
394
ca8aa8e9
DO
395function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
396{
397 echo getImageHREF ($tag, $title, $do_input, $tabindex);
398}
399
400// this would be better called mkIMG(), make "IMG" HTML element
401function getImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
402{
403 global $image;
404 if (!isset ($image[$tag]))
405 $tag = 'error';
406 $img = $image[$tag];
19f22ad8 407 $img['path'] = '?module=chrome&uri=' . $img['path'];
ca8aa8e9
DO
408 if ($do_input == TRUE)
409 return
410 "<input type=image name=submit class=icon " .
411 "src='${img['path']}' " .
412 "border=0 " .
413 ($tabindex ? "tabindex=${tabindex}" : '') .
414 (!strlen ($title) ? '' : " title='${title}'") . // JT: Add title to input hrefs too
415 ">";
416 else
417 return
418 "<img " .
419 "src='${img['path']}' " .
420 "width=${img['width']} " .
421 "height=${img['height']} " .
422 "border=0 " .
423 (!strlen ($title) ? '' : "title='${title}'") .
424 ">";
425}
426
967e3845
DO
427function dos2unix ($text)
428{
429 return str_replace ("\r\n", "\n", $text);
430}
431
432function escapeString ($value, $do_db_escape = FALSE)
433{
434 $ret = htmlspecialchars ($value, ENT_QUOTES, 'UTF-8');
435 if ($do_db_escape)
436 {
437 global $dbxlink;
438 $ret = substr ($dbxlink->quote ($ret), 1, -1);
439 }
440 return $ret;
441}
442
443function transformRequestData()
444{
445 global $sic;
446 // Magic quotes feature is deprecated, but just in case the local system
447 // still has it activated, reverse its effect.
dbd20c7e
AA
448 $do_magic_quotes = (function_exists ('get_magic_quotes_gpc') and get_magic_quotes_gpc());
449 $seen_keys = array();
450
967e3845
DO
451 // Escape any globals before we ever try to use them, but keep a copy of originals.
452 $sic = array();
4675424f
AA
453 // walk through merged GET and POST instead of REQUEST array because it
454 // can contain cookies with data which could not be decoded from UTF-8
4675424f 455 foreach (array_merge($_GET, $_POST) as $key => $value)
967e3845 456 {
5a7dc9e7
AA
457 if (is_array ($value))
458 $_REQUEST[$key] = $value;
459 else
460 {
461 $value = dos2unix ($value);
462 if ($do_magic_quotes)
463 $value = stripslashes ($value);
464 $_REQUEST[$key] = escapeString ($value);
465 }
466 $sic[$key] = $value;
dbd20c7e 467 $seen_keys[$key] = 1;
967e3845
DO
468 }
469
dbd20c7e
AA
470 // delete cookie information from the $_REQUEST array
471 foreach (array_keys ($_REQUEST) as $key)
472 if (! isset ($seen_keys[$key]))
473 unset ($_REQUEST[$key]);
474
967e3845
DO
475 if (isset ($_SERVER['PHP_AUTH_USER']))
476 $_SERVER['PHP_AUTH_USER'] = escapeString ($_SERVER['PHP_AUTH_USER']);
477 if (isset ($_SERVER['REMOTE_USER']))
478 $_SERVER['REMOTE_USER'] = escapeString ($_SERVER['REMOTE_USER']);
479}
480
ca6698d8
AA
481// JS scripts should be included through this function.
482// They automatically appear in the <head> of your page.
483// $data is a JS filename, or JS code w/o tags around, if $inline = TRUE
484// Scripts are included in the order of adding within the same group, and groups are sorted alphabetically.
485function addJS ($data, $inline = FALSE, $group = 'default')
486{
487 static $javascript = array();
488 static $seen_filenames = array();
489
490 if (! isset ($data))
491 {
492 ksort ($javascript);
493 return $javascript;
494 }
495 // Add jquery.js and racktables.js the first time a Javascript file is added.
496 if (empty($javascript))
497 {
498 $javascript = array
499 (
500 'a_core' => array
501 (
502 array('type' => 'file', 'script' => 'js/jquery-1.4.4.min.js'),
503 array('type' => 'file', 'script' => 'js/racktables.js'),
504 ),
505 );
506
507 // initialize core js filelist
508 foreach ($javascript as $group_name => $group_array)
509 foreach ($group_array as $item)
510 if ($item['type'] == 'file')
511 $seen_filenames[$item['script']] = 1;
512 }
513
514 if ($inline)
515 $javascript[$group][] = array
516 (
517 'type' => 'inline',
518 'script' => $data,
519 );
520 elseif (! isset ($seen_filenames[$data]))
521 {
522 $javascript[$group][] = array
523 (
524 'type' => 'file',
525 'script' => $data,
526 );
527 $seen_filenames[$data] = 1;
528 }
529}
530
531// CSS styles should be included through this function.
532// They automatically appear in the <head> of your page.
533// $data is a CSS filename, or CSS code w/o tags around, if $inline = TRUE
534// Styles are included in the order of adding.
535function addCSS ($data, $inline = FALSE)
536{
537 static $styles = array();
538 static $seen_filenames = array();
539
540 if (! isset ($data))
541 return $styles;
542 if ($inline)
543 $styles[] = array
544 (
545 'type' => 'inline',
546 'style' => $data,
547 );
548 elseif (! isset ($seen_filenames[$data]))
549 {
550 $styles[] = array
551 (
552 'type' => 'file',
553 'style' => $data,
554 );
555 $seen_filenames[$data] = 1;
556 }
557}
558
559// print part of HTML HEAD block
560function printPageHeaders ()
561{
562 global $pageheaders;
563 ksort ($pageheaders);
564 foreach ($pageheaders as $s)
565 echo $s . "\n";
566
567 // add CSS styles
568 foreach (addCSS (NULL) as $item)
569 if ($item['type'] == 'inline')
570 echo '<style type="text/css">' . "\n" . trim ($item['style'], "\r\n") . "\n</style>\n";
571 elseif ($item['type'] == 'file')
572 echo "<link rel=stylesheet type='text/css' href='?module=chrome&uri=${item['style']}' />\n";
573
574 // add JS scripts
575 foreach (addJS (NULL) as $group_name => $js_list)
576 foreach ($js_list as $item)
577 if ($item['type'] == 'inline')
578 echo '<script type="text/javascript">' . "\n" . trim ($item['script'], "\r\n") . "\n</script>\n";
579 elseif ($item['type'] == 'file')
580 echo "<script type='text/javascript' src='?module=chrome&uri=${item['script']}'></script>\n";
581}
582
d3535346
DO
583function validTagName ($s, $allow_autotag = FALSE)
584{
585 if (1 == preg_match (TAGNAME_REGEXP, $s))
586 return TRUE;
587 if ($allow_autotag and 1 == preg_match (AUTOTAGNAME_REGEXP, $s))
588 return TRUE;
589 return FALSE;
590}
591
221327e3
DO
592function serializeTags ($chain, $baseurl = '')
593{
594 $tmp = array();
595 foreach ($chain as $taginfo)
30bb83bd 596 {
d3ee17b7
AA
597 if ($baseurl == '')
598 $tmp[] = $taginfo['tag'];
30bb83bd 599 else
d3ee17b7 600 {
30bb83bd 601 $title = '';
d3ee17b7
AA
602 if (isset ($taginfo['user']) and isset ($taginfo['time']))
603 $title = 'title="' . htmlspecialchars ($taginfo['user'] . ', ' . formatAge ($taginfo['time']), ENT_QUOTES) . '"';
604 $tmp[] = "<a $title href='${baseurl}cft[]=${taginfo['id']}'>" . $taginfo['tag'] . "</a>";
605 }
30bb83bd 606 }
221327e3
DO
607 return implode (', ', $tmp);
608}
609
2030a7f2
AA
610function startPortlet ($title = '')
611{
612 echo "<div class=portlet><h2>${title}</h2>";
613}
614
615function finishPortlet ()
616{
617 echo "</div>\n";
618}
619
a1d72d2e
AA
620function getPageName ($page_code)
621{
622 global $page;
623 $title = isset ($page[$page_code]['title']) ? $page[$page_code]['title'] : dynamic_title_decoder ($page_code);
624 if (is_array ($title))
625 $title = $title['name'];
626 return $title;
627}
628
ca8aa8e9 629?>