There are two scripts that make up the
PHP configuration - the
generated stylesheet, udm-style.php
, and the generated
menu script, udm-dom.php
. These are controlled from a
configuration file called udm-custom.ini
For the head section you need a single
<link />
element to include the
generated stylesheet, udm-style.php
:
<!-- ULTIMATE DROP DOWN MENU Version 4.6 by Brothercake -->
<!-- http://www.udm4.com/ -->
<!-- PHP generated stylesheet -->
<link rel="stylesheet" type="text/css" media="screen,projection"
href="/udm-resources/udm-style.php" />
Other things being equal it can go anywhere in the head section. However since global styles can potentially affect the menus, but the menu styles are extremely unlikely to affect other rules, it's best to put it after any other style sheets.
The media attribute serves a twin purpose here - because Opera in fullscreen mode uses projection-media CSS, not screen, and because the comma-delimited syntax is not understood by primitive CSS browsers like Netscape 4, and so it won't process that stylesheet at all.
In the body section you need a single
script include for the generated menu script, udm-dom.php
.
It must go in the <body>
-
if you put it in the <head>
then it
won't work in Mac/IE5.
As with the script in the head section,
it doesn't need a language
attribute:
<!-- PHP generated menu script [any modules or extensions must come AFTER this] -->
<script type="text/javascript"
src="/udm-resources/udm-dom.php"></script>
Within the body section it can go anywhere, however if you have
an existing window.onload
function on your page then the script
should come after it, to avoid an
onload conflict in Mac/IE5.
The DOM
script provides core functionality, but does not include full keyboard access.
For best accessibility I strongly recommend including the
keyboard navigation module
as well (which you already have in your udm-resources
folder).
This should come after the udm-dom.php
script include:
<script type="text/javascript"
src="/udm-resources/udm-mod-keyboard.js"></script>
If you're using any other
modules or
extensions, these must also
go in the body section and come somewhere after the
udm-dom.php
script include.
The udm-custom.ini
configuration file is used by both scripts,
and so both will need to know the
path to it. Open the two files in your text editor and
you'll see the variable you need to set near the top -
the path must be server-absolute,
so I've used DOCUMENT_ROOT
:
//set a path to the configuration file
$config = $_SERVER['DOCUMENT_ROOT'] . '/udm-resources/udm-custom.ini';
If you need an alternative to DOCUMENT_ROOT
,
you can extrapolate the script's directory path
using the
"magic" constant
__FILE__
:
//set a path to the configuration file
$config = str_replace(basename(__FILE__), '', realpath(__FILE__)) . 'udm-custom.ini';
The configuration file itself
doesn't need to be parsed separately by
PHP, however since it has a plain-text extension
it will be readable across
HTTP
to anyone who works out its address.
I can't see how that would be a problem, but if it is
you can just rename it .php
The page that the menu is on doesn't actually need to be parsed by PHP either - it's only the two included scripts that do - so you have the freedom to use this configuration language on pages built in a different one.
If you want to use a configuration file other than the default, you can pass its path to the scripts as a query-string value. The specified value can only contain letters, numbers, dot, dash, underscore or slash. The file path must also be server-absolute:
<?php $config = $_SERVER['DOCUMENT_ROOT'] . '/path/to/config.ini'; ?>
then:
<link rel="stylesheet" type="text/css" media="screen,projection"
href="/udm-resources/udm-style.php?config=<?php echo($config); ?>" />
and:
<script type="text/javascript"
src="/udm-resources/udm-dom.php?config=<?php echo($config); ?>"></script>
The ability to specify a different configuration file exposes a potential vulnerability that could allow for malicious code injections. In order to prevent that, the input filename is validated in two passes:
$cmatch
variable?
The $cmatch
expression can be defined
to suit the pattern of filenames you'll
be using. By default, only configuration files called
"udm-custom.ini"
are allowed:
//specify config file value match
$cmatch = 'udm-custom.ini';
But you could change this, for example, so that filenames
like "foo-bar.php"
and "foo_bar.ini"
are allowed:
//specify config file value match
$cmatch = '([a-z]+[\-_]?)+[\.](ini|php)';
You should set the $cmatch
expression as tight as possible,
and not rely on the general regex to stop all attacks - it won't. The only
way to be sure that only valid configuration files are allowed through, is
to define absolutely what those files will be called.
UDM 4 is valid XHTML, and in our judgement, meets the criteria for WAI Triple-A conformance.