.. index::
   single: VALIDATION

.. _validation:

*****************************************************************************
 VALIDATION
*****************************************************************************

.. contents::
    :depth: 3
    :backlinks: top

Introduction
-------------------------------------------------------------------------------

Because :ref:`runsub` affects potentially sensitive areas of your
mapfile such as database columns and filenames, it is mandatory that
you use pattern validation (since version 6.0).

.. note:: 

  Similar validation pattern mechanisms have been available for
  variable substitutions since version 4.10, but then it was optional.
  The pattern for %myvar% was then provided in `METADATA` using
  "myvar_validation_pattern".

Pattern validation uses regular expressions, which are strings that
describe how to compare strings to patterns.  The exact functionality
of your systems' regular expressions may vary, but you can find a lot
of general information by a Google search for "regular expression
tutorial".

As of MapServer 5.4.0 the preferred mechanism is a `VALIDATION` block
in the `LAYER` definition.  This is only slightly different from the
older `METADATA` mechanism.  `VALIDATION` blocks can be used with
:ref:`CLASS`, :ref:`LAYER` and :ref:`WEB`.

.. code-block:: mapfile

    VALIDATION
      # %firstname% substitutions can only have letters and hyphens
      'firstname'     '^[a-zA-Z\-]+$'

      # %parcelid% must be numeric and between 5 and 8 characters
      'parcelid'      '^[0-9]{5,8)$'

      # %taxid% must be two capital letters and six digits
      'taxid'         '^[A-Z]{2}[0-9]{6}$'
    END

If identical keys appear in more than one validation block, then keys
in more specialised blocks override those in more generalised blocks.
So :ref:`CLASS` overrides :ref:`LAYER` which overrides :ref:`WEB`.


Default values if not provided in the URL
--------------------------------------------------------------------------------

The runtime substitution mechanism will usually create syntactically
incorrect, and almost always semantically incorrect mapfiles if the
substitution parameter was not provided in the calling URL.

Since version 5.6, you can provide a default value for any
substitution parameter, that will be applied if the parameter was not
found in the url. You do this by providing special entries inside
:ref:`CLASS`, :ref:`LAYER` or :ref:`WEB` validation blocks:

.. code-block:: mapfile

    VALIDATION
        'default_sound' 'yes'
        'default_nseats' '5'
        'default_multimedia' 'yes'
    END

In this example, the mapfile will be created as if the url contained 
"&sound=yes&nseats=5&multimedia=yes"

If identical default keys appear in more than one validation block
then keys in more specialised blocks override those in more
generalised blocks. i.e. `CLASS` overrides `LAYER` which overrides
`WEB`.

The same functionality is available using `METADATA` blocks instead of
`VALIDATION` but this is deprecated as of MapServer 5.4.0.

This behavior is also accessible in the shp2img utility, allowing you
to test runtime substitution mapfiles without using a webserver.



Filter example
---------------------------------------------------------------

You can use runtime substitutions to change values within a FILTER as
you go.  For example your FILTER could be written like this::

    FILTER ("multimedia='%multimedia%' and seats >= %nseats% and Sound= '%sound%')

Then (assuming you're using the CGI interface) you could pass in
variables named multimedia, nseats and sound with values defined by
the user in an HTML form.

You must define validation expressions on these variables to guard
against unintentional SQL being submitted to postgis. Within the layer
you'd do the following:

.. code-block:: mapfile

    VALIDATION
        'multimedia' '^yes|no$'
        'sound' '^yes|no$'
        'nseats' '^[0-9]{1,2}$'
    END

The first two limit the value of multimedia and sound to yes or
no. The third limits the value for nseats to a 2 digit integer.
