<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.filter.input">
    <title>Zend_Filter_Input</title>

    <para>
        <classname>Zend_Filter_Input</classname> provides a declarative interface to associate
        multiple filters and validators, apply them to collections of data, and
        to retrieve input values after they have been processed by the filters
        and validators. Values are returned in escaped format by default for
        safe <acronym>HTML</acronym> output.
    </para>

    <para>
        Consider the metaphor that this class is a cage for external data.
        Data enter the application from external sources, such as <acronym>HTTP</acronym> request
        parameters, <acronym>HTTP</acronym> headers, a web service, or even read from a database
        or another file. Data are first put into the cage, and subsequently
        the application can access data only by telling the cage what the data
        should be and how they plan to use it. The cage inspects the data for
        validity. It might apply escaping to the data values for the
        appropriate context. The cage releases data only if it can fulfill
        these responsibilities. With a simple and convenient interface, it
        encourages good programming habits and makes developers think about how
        data are used.
    </para>

    <itemizedlist>
        <listitem>
            <para>
                <emphasis>Filters</emphasis> transform input
                values, by removing or changing characters within the value.
                The goal is to "normalize" input values until they match an
                expected format. For example, if a string of numeric digits is
                needed, and the input value is "abc123", then it might be a
                reasonable transformation to change the value to the string
                "123".
            </para>
        </listitem>
        <listitem>
            <para>
                <emphasis>Validators</emphasis> check input
                values against criteria and report whether they passed the test
                or not. The value is not changed, but the check may fail. For
                example, if a string must look like an email address, and the
                input value is "abc123", then the value is not considered
                valid.
            </para>
        </listitem>
        <listitem>
            <para>
                <emphasis>Escapers</emphasis> transform a value
                by removing magic behavior of certain characters. In some
                output contexts, special characters have meaning. For example,
                the characters '&lt;' and '&gt;' delimit <acronym>HTML</acronym> tags, and if a
                string containing those characters is output in an <acronym>HTML</acronym>
                context, the content between them might affect the output or
                functionality of the <acronym>HTML</acronym> presentation. Escaping the
                characters removes the special meaning, so they are output as
                literal characters.
            </para>
        </listitem>
    </itemizedlist>

    <para>
        To use <classname>Zend_Filter_Input</classname>, perform the following steps:
    </para>

    <orderedlist numeration="arabic">
        <listitem>
            <para>
                Declare filter and validator rules
            </para>
        </listitem>
        <listitem>
            <para>
                Create the filter and validator processor
            </para>
        </listitem>
        <listitem>
            <para>
                Provide input data
            </para>
        </listitem>
        <listitem>
            <para>
                Retrieve validated fields and other reports
            </para>
        </listitem>
    </orderedlist>

    <para>
        The following sections describe the steps for using this class.
    </para>

    <sect2 id="zend.filter.input.declaring">

        <title>Declaring Filter and Validator Rules</title>

        <para>
            Before creating an instance of <classname>Zend_Filter_Input</classname>, declare an
            array of filter rules and an array of validator rules.
            This associative array maps a rule name to a filter or
            validator or a chain of filters or validators.
        </para>

        <para>
            The following example filter rule set that declares the field
            'month' is filtered by <classname>Zend_Filter_Digits</classname>, and the field
            'account' is filtered by <classname>Zend_Filter_StringTrim</classname>. Then a
            validation rule set declares that the field 'account' is valid only if it contains only
            alphabetical characters.
        </para>

        <programlisting language="php"><![CDATA[
$filters = array(
    'month'   => 'Digits',
    'account' => 'StringTrim'
);

$validators = array(
    'account' => 'Alpha'
);
]]></programlisting>

        <para>
            Each key in the <varname>$filters</varname> array above is the name of a rule for
            applying a filter to a specific data field. By default, the name of the rule
            is also the name of the input data field to which to apply the rule.
        </para>

        <para>
            You can declare a rule in several formats:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    A single string scalar, which is mapped to a class name.
                </para>

                <programlisting language="php"><![CDATA[
$validators = array(
    'month'   => 'Digits',
);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    An object instance of one of the classes that implement
                    <classname>Zend_Filter_Interface</classname> or
                    <classname>Zend_Validate_Interface</classname>.
                </para>

                <programlisting language="php"><![CDATA[
$digits = new Zend_Validate_Digits();

$validators = array(
    'month'   => $digits
);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    An array, to declare a chain of filters or validators.
                    The elements of this array can be strings mapping to class
                    names or filter/validator objects, as in the cases
                    described above. In addition, you can use a third choice:
                    an array containing a string mapping to the class name
                    followed by arguments to pass to its constructor.
                </para>

                <programlisting language="php"><![CDATA[
$validators = array(
    'month'   => array(
        'Digits',                // string
        new Zend_Validate_Int(), // object instance
        array('Between', 1, 12)  // string with constructor arguments
    )
);
]]></programlisting>
            </listitem>
        </itemizedlist>

        <note>
            <para>
                If you declare a filter or validator with constructor arguments
                in an array, then you must make an array for the rule, even if
                the rule has only one filter or validator.
            </para>
        </note>

        <para>
            You can use a special "wildcard" rule key <emphasis>'*'</emphasis> in
            either the filters array or the validators array. This means that
            the filters or validators declared in this rule will be applied to
            all input data fields. Note that the order of entries in the
            filters array or validators array is significant; the rules are
            applied in the same order in which you declare them.
        </para>

        <programlisting language="php"><![CDATA[
$filters = array(
    '*'     => 'StringTrim',
    'month' => 'Digits'
);
]]></programlisting>
    </sect2>

    <sect2 id="zend.filter.input.running">
        <title>Creating the Filter and Validator Processor</title>

        <para>
            After declaring the filters and validators arrays, use them as
            arguments in the constructor of <classname>Zend_Filter_Input</classname>. This returns
            an object that knows all your filtering and validating rules, and you
            can use this object to process one or more sets of input data.
        </para>

        <programlisting language="php"><![CDATA[
$input = new Zend_Filter_Input($filters, $validators);
]]></programlisting>

        <para>
            You can specify input data as the third constructor argument. The
            data structure is an associative array. The keys are field names,
            and the values are data values. The standard <varname>$_GET</varname>
            and <varname>$_POST</varname> superglobal variables in <acronym>PHP</acronym> are
            examples of this format. You can use either of these variables as input
            data for <classname>Zend_Filter_Input</classname>.
        </para>

        <programlisting language="php"><![CDATA[
$data = $_GET;

$input = new Zend_Filter_Input($filters, $validators, $data);
]]></programlisting>

        <para>
            Alternatively, use the <methodname>setData()</methodname> method, passing
            an associative array of key/value pairs the same format as
            described above.
        </para>

        <programlisting language="php"><![CDATA[
$input = new Zend_Filter_Input($filters, $validators);
$input->setData($newData);
]]></programlisting>

        <para>
            The <methodname>setData()</methodname> method redefines data in an existing
            <classname>Zend_Filter_Input</classname> object without changing the filtering and
            validation rules. Using this method, you can run the same rules
            against different sets of input data.
        </para>
    </sect2>

    <sect2 id="zend.filter.input.results">
        <title>Retrieving Validated Fields and other Reports</title>

        <para>
            After you have declared filters and validators and created the
            input processor, you can retrieve reports of missing, unknown, and
            invalid fields. You also can get the values of fields after
            filters have been applied.
        </para>

        <sect3 id="zend.filter.input.results.isvalid">
            <title>Querying if the input is valid</title>

            <para>
                If all input data pass the validation rules, the
                <methodname>isValid()</methodname> method returns <constant>TRUE</constant>.
                If any field is invalid or any required field is missing,
                <methodname>isValid()</methodname> returns <constant>FALSE</constant>.
            </para>

            <programlisting language="php"><![CDATA[
if ($input->isValid()) {
  echo "OK\n";
}
]]></programlisting>

            <para>
                This method accepts an optional string argument, naming
                an individual field. If the specified field passed validation
                and is ready for fetching, <methodname>isValid('fieldName')</methodname>
                returns <constant>TRUE</constant>.
            </para>

            <programlisting language="php"><![CDATA[
if ($input->isValid('month')) {
  echo "Field 'month' is OK\n";
}
]]></programlisting>
        </sect3>

        <sect3 id="zend.filter.input.results.reports">
            <title>Getting Invalid, Missing, or Unknown Fields</title>

            <itemizedlist>
                <listitem>
                    <para>
                        <emphasis>Invalid</emphasis> fields are
                        those that don't pass one or more of their validation
                        checks.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis>Missing</emphasis> fields are
                        those that are not present in the input data, but were
                        declared with the metacommand
                        <command>'presence'=>'required'</command> (see the
                        <link linkend="zend.filter.input.metacommands.presence">later section</link>
                        on metacommands).
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis>Unknown</emphasis> fields are
                        those that are not declared in any rule in the array of
                        validators, but appear in the input data.
                    </para>
                </listitem>
            </itemizedlist>

            <programlisting language="php"><![CDATA[
if ($input->hasInvalid() || $input->hasMissing()) {
  $messages = $input->getMessages();
}

// getMessages() simply returns the merge of getInvalid() and
// getMissing()

if ($input->hasInvalid()) {
  $invalidFields = $input->getInvalid();
}

if ($input->hasMissing()) {
  $missingFields = $input->getMissing();
}

if ($input->hasUnknown()) {
  $unknownFields = $input->getUnknown();
}
]]></programlisting>

            <para>
                The results of the <methodname>getMessages()</methodname> method is an
                associative array, mapping a rule name to an array of error
                messages related to that rule. Note that the index of this
                array is the rule name used in the rule declaration, which may
                be different from the names of fields checked by the rule.
            </para>

            <para>
                The <methodname>getMessages()</methodname> method returns the merge of the
                arrays returned by the <methodname>getInvalid()</methodname> and
                <methodname>getMissing()</methodname>. These methods return subsets of the
                messages, related to validation failures, or fields that were
                declared as required but missing from the input.
            </para>

            <para>
                The <methodname>getErrors()</methodname> method returns an associative array,
                mapping a rule name to an array of error identifiers. Error
                identifiers are fixed strings, to identify the reason for a
                validation failure, while messages can be customized.
                See <link linkend="zend.validate.introduction.using">this chapter</link> for
                more information.
            </para>

            <para>
                You can specify the message returned by
                <methodname>getMissing()</methodname> using the 'missingMessage' option,
                as an argument to the <classname>Zend_Filter_Input</classname> constructor or using
                the <methodname>setOptions()</methodname> method.
            </para>

            <programlisting language="php"><![CDATA[
$options = array(
    'missingMessage' => "Field '%field%' is required"
);

$input = new Zend_Filter_Input($filters, $validators, $data, $options);

// alternative method:

$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setOptions($options);
]]></programlisting>

            <para>
                And you can also add a translator which gives you the ability to provide multiple
                languages for the messages which are returned by
                <classname>Zend_Filter_Input</classname>.
            </para>

            <programlisting language="php"><![CDATA[
$translate = new Zend_Translate_Adapter_Array(array(
    'content' => array(
        Zend_Filter_Input::MISSING_MESSAGE => "Where is the field?"
    )
);

$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setTranslator($translate);
]]></programlisting>

            <para>
                When you are using an application wide translator, then it will also be used by
                <classname>Zend_Filter_Input</classname>. In this case you will not have to set the
                translator manually.
            </para>

            <para>
                The results of the <methodname>getUnknown()</methodname> method is an
                associative array, mapping field names to field values. Field
                names are used as the array keys in this case, instead of rule
                names, because no rule mentions the fields considered to be
                unknown fields.
            </para>
        </sect3>

        <sect3 id="zend.filter.input.results.escaping">
            <title>Getting Valid Fields</title>

            <para>
                All fields that are neither invalid, missing, nor unknown are
                considered valid. You can get values for valid fields using a
                magic accessor. There are also non-magic accessor methods
                <methodname>getEscaped()</methodname> and <methodname>getUnescaped()</methodname>.
            </para>

            <programlisting language="php"><![CDATA[
$m = $input->month;                 // escaped output from magic accessor
$m = $input->getEscaped('month');   // escaped output
$m = $input->getUnescaped('month'); // not escaped
]]></programlisting>

            <para>
                By default, when retrieving a value, it is filtered with the
                <classname>Zend_Filter_HtmlEntities</classname>. This is the default because it is
                considered the most common usage to output the value of a field
                in <acronym>HTML</acronym>. The HtmlEntities filter helps prevent unintentional
                output of code, which can result in security problems.
            </para>

            <note>
                <para>
                    As shown above, you can retrieve the unescaped value using
                    the <methodname>getUnescaped()</methodname> method, but you must write
                    code to use the value safely, and avoid security issues
                    such as vulnerability to cross-site scripting attacks.
                </para>
            </note>

            <warning>
                <title>Escaping unvalidated fields</title>

                <para>
                    As mentioned before <methodname>getEscaped()</methodname> returns only validated
                    fields. Fields which do not have an associated validator can not be received
                    this way. Still, there is a possible way. You can add a empty validator for all
                    fields.
                </para>

                <programlisting language="php"><![CDATA[
$validators = array('*' => array());

$input = new Zend_Filter_Input($filters, $validators, $data, $options);
]]></programlisting>

                <para>
                    But be warned that using this notation introduces a security leak which could
                    be used for cross-site scripting attacks. Therefor you should always set
                    individual validators for each field.
                </para>
            </warning>

            <para>
                You can specify a different filter for escaping values, by
                specifying it in the constructor options array:
            </para>

            <programlisting language="php"><![CDATA[
$options = array('escapeFilter' => 'StringTrim');
$input = new Zend_Filter_Input($filters, $validators, $data, $options);
]]></programlisting>

            <para>
                Alternatively, you can use the
                <methodname>setDefaultEscapeFilter()</methodname> method:
            </para>

            <programlisting language="php"><![CDATA[
$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setDefaultEscapeFilter(new Zend_Filter_StringTrim());
]]></programlisting>

            <para>
                In either usage, you can specify the escape filter as a string
                base name of the filter class, or as an object instance of a
                filter class. The escape filter can be an instance of a filter
                chain, an object of the class <classname>Zend_Filter</classname>.
            </para>

            <para>
                Filters to escape output should be run in this way, to make
                sure they run after validation. Other filters you declare in
                the array of filter rules are applied to input data before data
                are validated. If escaping filters were run before validation,
                the process of validation would be more complex, and it would
                be harder to provide both escaped and unescaped versions of the
                data. So it is recommended to declare filters to escape output
                using <methodname>setDefaultEscapeFilter()</methodname>, not in the
                <varname>$filters</varname> array.
            </para>

            <para>
                There is only one method <methodname>getEscaped()</methodname>, and
                therefore you can specify only one filter for escaping
                (although this filter can be a filter chain). If you need a
                single instance of <classname>Zend_Filter_Input</classname> to return escaped output
                using more than one filtering method, you should extend
                <classname>Zend_Filter_Input</classname> and implement new methods in your subclass
                to get values in different ways.
            </para>
        </sect3>
    </sect2>

    <sect2 id="zend.filter.input.metacommands">
        <title>Using Metacommands to Control Filter or Validator Rules</title>

        <para>
            In addition to declaring the mapping from fields to filters
            or validators, you can specify some "metacommands" in the array
            declarations, to control some optional behavior of
            <classname>Zend_Filter_Input</classname>. Metacommands appear as string-indexed
            entries in a given filter or validator array value.
        </para>

        <sect3 id="zend.filter.input.metacommands.fields">
            <title>The FIELDS metacommand</title>

            <para>
                If the rule name for a filter or validator is different than
                the field to which it should apply, you can specify the
                field name with the 'fields' metacommand.
            </para>

            <para>
                You can specify this metacommand using the class constant
                <constant>Zend_Filter_Input::FIELDS</constant> instead of the
                string.
            </para>

            <programlisting language="php"><![CDATA[
$filters = array(
    'month' => array(
        'Digits',        // filter name at integer index [0]
        'fields' => 'mo' // field name at string index ['fields']
    )
);
]]></programlisting>

            <para>
                In the example above, the filter rule applies the 'digits'
                filter to the input field named 'mo'. The string 'month'
                simply becomes a mnemonic key for this filtering rule; it is
                not used as the field name if the field is specified with the
                'fields' metacommand, but it is used as the rule name.
            </para>

            <para>
                The default value of the 'fields' metacommand is the index of
                the current rule. In the example above, if the 'fields'
                metacommand is not specified, the rule would apply to the input
                field named 'month'.
            </para>

            <para>
                Another use of the 'fields' metacommand is to specify fields
                for filters or validators that require multiple fields as
                input. If the 'fields' metacommand is an array, the argument
                to the corresponding filter or validator is an array of the
                values of those fields. For example, it is common for users to
                specify a password string in two fields, and they must type the
                same string in both fields. Suppose you implement a validator
                class that takes an array argument, and returns
                <constant>TRUE</constant> if all the values in the array are equal to
                each other.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'password' => array(
        'StringEquals',
        'fields' => array('password1', 'password2')
    )
);
// Invokes hypothetical class Zend_Validate_StringEquals,
// passing an array argument containing the values of the two input
// data fields named 'password1' and 'password2'.
]]></programlisting>

            <para>
                If the validation of this rule fails, the rule key ('password') is used in the
                return value of <methodname>getInvalid()</methodname>, not any of the fields named
                in the 'fields' metacommand.
            </para>
        </sect3>

        <sect3 id="zend.filter.input.metacommands.presence">
            <title>The PRESENCE metacommand</title>

            <para>
                Each entry in the validator array may have a metacommand called
                'presence'. If the value of this metacommand is 'required'
                then the field must exist in the input data, or else it is
                reported as a missing field.
            </para>

            <para>
                You can specify this metacommand using the class constant
                <constant>Zend_Filter_Input::PRESENCE</constant> instead of the
                string.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        'digits',
        'presence' => 'required'
    )
);
]]></programlisting>

            <para>
                The default value of this metacommand is 'optional'.
            </para>
        </sect3>

        <sect3 id="zend.filter.input.metacommands.default">
            <title>The DEFAULT_VALUE metacommand</title>

            <para>
                If a field is not present in the input data, and you specify a
                value for the 'default' metacommand for that rule, the field
                takes the value of the metacommand.
            </para>

            <para>
                You can specify this metacommand using the class constant
                <constant>Zend_Filter_Input::DEFAULT_VALUE</constant> instead of the
                string.
            </para>

            <para>
                This default value is assigned to the field before any of the
                validators are invoked. The default value is applied to the
                field only for the current rule; if the same field is
                referenced in a subsequent rule, the field has no value when
                evaluating that rule. Thus different rules can declare
                different default values for a given field.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        'digits',
        'default' => '1'
    )
);

// no value for 'month' field
$data = array();

$input = new Zend_Filter_Input(null, $validators, $data);
echo $input->month; // echoes 1
]]></programlisting>

            <para>
                If your rule uses the <constant>FIELDS</constant> metacommand
                to define an array of multiple fields, you can define
                an array for the <constant>DEFAULT_VALUE</constant> metacommand
                and the defaults of corresponding keys are used for any
                missing fields. If <constant>FIELDS</constant> defines multiple
                fields but <constant>DEFAULT_VALUE</constant> is a scalar, then
                that default value is used as the value for any missing
                fields in the array.
            </para>

            <para>
                There is no default value for this metacommand.
            </para>
        </sect3>

        <sect3 id="zend.filter.input.metacommands.allow-empty">
            <title>The ALLOW_EMPTY metacommand</title>

            <para>
                By default, if a field exists in the input data, then
                validators are applied to it, even if the value of the field is
                an empty string (<emphasis>''</emphasis>). This is likely to result in
                a failure to validate. For example, if the validator checks
                for digit characters, and there are none because a zero-length
                string has no characters, then the validator reports the data
                as invalid.
            </para>

            <para>
                If in your case an empty string should be considered valid, you
                can set the metacommand 'allowEmpty' to <constant>TRUE</constant>.
                Then the input data passes validation if it is present in the
                input data, but has the value of an empty string.
            </para>

            <para>
                You can specify this metacommand using the class constant
                <constant>Zend_Filter_Input::ALLOW_EMPTY</constant> instead of the
                string.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'address2' => array(
        'Alnum',
        'allowEmpty' => true
    )
);
]]></programlisting>

            <para>
                The default value of this metacommand is <constant>FALSE</constant>.
            </para>

            <para>
                In the uncommon case that you declare a validation rule with
                no validators, but the 'allowEmpty' metacommand is
                <constant>FALSE</constant> (that is, the field is considered invalid if
                it is empty), <classname>Zend_Filter_Input</classname> returns a default error
                message that you can retrieve with <methodname>getMessages()</methodname>. You can
                specify this message using the 'notEmptyMessage' option, as an
                argument to the <classname>Zend_Filter_Input</classname> constructor or using the
                <methodname>setOptions()</methodname> method.
            </para>

            <programlisting language="php"><![CDATA[
$options = array(
    'notEmptyMessage' => "A non-empty value is required for field '%field%'"
);

$input = new Zend_Filter_Input($filters, $validators, $data, $options);

// alternative method:

$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setOptions($options);
]]></programlisting>
        </sect3>

        <sect3 id="zend.filter.input.metacommands.break-chain">
            <title>The BREAK_CHAIN metacommand</title>

            <para>
                By default if a rule has more than one validator, all
                validators are applied to the input, and the resulting messages
                contain all error messages caused by the input.
            </para>

            <para>
                Alternatively, if the value of the 'breakChainOnFailure'
                metacommand is <constant>TRUE</constant>, the validator chain
                terminates after the first validator fails. The input data is
                not checked against subsequent validators in the chain, so it
                might cause more violations even if you correct the one
                reported.
            </para>

            <para>
                You can specify this metacommand using the class constant
                <constant>Zend_Filter_Input::BREAK_CHAIN</constant> instead of the
                string.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        'Digits',
        new Zend_Validate_Between(1,12),
        new Zend_Validate_GreaterThan(0),
        'breakChainOnFailure' => true
    )
);
$input = new Zend_Filter_Input(null, $validators);
]]></programlisting>

            <para>
                The default value of this metacommand is <constant>FALSE</constant>.
            </para>

            <para>
                The validator chain class, <classname>Zend_Validate</classname>, is more flexible
                with respect to breaking chain execution than
                <classname>Zend_Filter_Input</classname>. With the former class, you can set the
                option to break the chain on failure independently for each validator in the chain.
                With the latter class, the defined value of the
                'breakChainOnFailure' metacommand for a rule applies uniformly
                for all validators in the rule. If you require the more
                flexible usage, you should create the validator chain yourself,
                and use it as an object in the validator rule
                definition:
            </para>

            <programlisting language="php"><![CDATA[
// Create validator chain with non-uniform breakChainOnFailure
// attributes
$chain = new Zend_Validate();
$chain->addValidator(new Zend_Validate_Digits(), true);
$chain->addValidator(new Zend_Validate_Between(1,12), false);
$chain->addValidator(new Zend_Validate_GreaterThan(0), true);

// Declare validator rule using the chain defined above
$validators = array(
    'month' => $chain
);
$input = new Zend_Filter_Input(null, $validators);
]]></programlisting>
        </sect3>

        <sect3 id="zend.filter.input.metacommands.messages">
            <title>The MESSAGES metacommand</title>

            <para>
                You can specify error messages for each validator in a rule
                using the metacommand 'messages'. The value of this metacommand
                varies based on whether you have multiple validators in the
                rule, or if you want to set the message for a specific error
                condition in a given validator.
            </para>

            <para>
                You can specify this metacommand using the class constant
                <constant>Zend_Filter_Input::MESSAGES</constant> instead of the
                string.
            </para>

            <para>
                Below is a simple example of setting the default error message
                for a single validator.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        'digits',
        'messages' => 'A month must consist only of digits'
    )
);
]]></programlisting>

            <para>
                If you have multiple validators for which you want to set the
                error message, you should use an array for the value of the
                'messages' metacommand.
            </para>

            <para>
                Each element of this array is applied to the validator at the
                same index position. You can specify a message for the
                validator at position <emphasis>n</emphasis> by using the value
                <emphasis>n</emphasis> as the array index. Thus you can allow
                some validators to use their default message, while setting the
                message for a subsequent validator in the chain.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        'digits',
        new Zend_Validate_Between(1, 12),
        'messages' => array(
            // use default message for validator [0]
            // set new message for validator [1]
            1 => 'A month value must be between 1 and 12'
        )
    )
);
]]></programlisting>

            <para>
                If one of your validators has multiple error messages, they are
                identified by a message key. There are different keys in each
                validator class, serving as identifiers for error messages that
                the respective validator class might generate. Each validate
                class defines constants for its message keys. You can use
                these keys in the 'messages' metacommand by passing an
                associative array instead of a string.
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        'digits', new Zend_Validate_Between(1, 12),
        'messages' => array(
            'A month must consist only of digits',
            array(
                Zend_Validate_Between::NOT_BETWEEN =>
                    'Month value %value% must be between ' .
                    '%min% and %max%',
                Zend_Validate_Between::NOT_BETWEEN_STRICT =>
                    'Month value %value% must be strictly between ' .
                    '%min% and %max%'
            )
        )
    )
);
]]></programlisting>

            <para>
                You should refer to documentation for each validator class to
                know if it has multiple error messages, the keys of these
                messages, and the tokens you can use in the message templates.
            </para>

            <para>
                If you have only one validator in validation rule or all used validators
                has the same messages set, then they can be referenced without additional
                array construction:
            </para>

            <programlisting language="php"><![CDATA[
$validators = array(
    'month' => array(
        new Zend_Validate_Between(1, 12),
        'messages' => array(
                        Zend_Validate_Between::NOT_BETWEEN =>
                            'Month value %value% must be between ' .
                            '%min% and %max%',
                        Zend_Validate_Between::NOT_BETWEEN_STRICT =>
                            'Month value %value% must be strictly between ' .
                            '%min% and %max%'
        )
    )
);
]]></programlisting>
        </sect3>

        <sect3 id="zend.filter.input.metacommands.global">
            <title>Using options to set metacommands for all rules</title>

            <para>
                The default value for 'allowEmpty', 'breakChainOnFailure', and
                'presence' metacommands can be set for all rules using the
                <varname>$options</varname> argument to the constructor of
                <classname>Zend_Filter_Input</classname>. This allows you to set the default value
                for all rules, without requiring you to set the metacommand for
                every rule.
            </para>

            <programlisting language="php"><![CDATA[
// The default is set so all fields allow an empty string.
$options = array('allowEmpty' => true);

// You can override this in a rule definition,
// if a field should not accept an empty string.
$validators = array(
    'month' => array(
        'Digits',
        'allowEmpty' => false
    )
);

$input = new Zend_Filter_Input($filters, $validators, $data, $options);
]]></programlisting>

            <para>
                The 'fields', 'messages', and 'default' metacommands cannot be
                set using this technique.
            </para>
        </sect3>
    </sect2>

    <sect2 id="zend.filter.input.namespaces">
        <title>Adding Filter Class Namespaces</title>

        <para>
            By default, when you declare a filter or validator as a string,
            <classname>Zend_Filter_Input</classname> searches for the corresponding classes under
            the <classname>Zend_Filter</classname> or <classname>Zend_Validate</classname>
            namespaces. For example, a filter named by the string 'digits' is found in the class
            <classname>Zend_Filter_Digits</classname>.
        </para>

        <para>
            If you write your own filter or validator classes, or use filters
            or validators provided by a third-party, the classes may exist in
            different namespaces than <classname>Zend_Filter</classname> or
            <classname>Zend_Validate</classname>. You can tell
            <classname>Zend_Filter_Input</classname> to search more namespaces. You can specify
            namespaces in the constructor options:
        </para>

        <programlisting language="php"><![CDATA[
$options = array('filterNamespace' => 'My_Namespace_Filter',
                 'validatorNamespace' => 'My_Namespace_Validate');
$input = new Zend_Filter_Input($filters, $validators, $data, $options);
]]></programlisting>

        <para>
            Alternatively, you can use the <methodname>addValidatorPrefixPath($prefix,
                $path)</methodname> or <methodname>addFilterPrefixPath($prefix, $path)</methodname>
            methods, which directly proxy to the plugin loader that is used by
            <classname>Zend_Filter_Input</classname>:
        </para>

        <programlisting language="php"><![CDATA[
$input->addValidatorPrefixPath('Other_Namespace', 'Other/Namespace');
$input->addFilterPrefixPath('Foo_Namespace', 'Foo/Namespace');

// Now the search order for validators is:
// 1. My_Namespace_Validate
// 2. Other_Namespace
// 3. Zend_Validate

// The search order for filters is:
// 1. My_Namespace_Filter
// 2. Foo_Namespace
// 3. Zend_Filter
]]></programlisting>

        <para>
            You cannot remove <classname>Zend_Filter</classname> and
            <classname>Zend_Validate</classname> as namespaces, you only can add namespaces.
            User-defined namespaces are searched first, Zend namespaces are searched last.
        </para>

        <note>
            <para>
                As of version 1.5 the function <methodname>addNamespace($namespace)</methodname>
                was deprecated and exchanged with the plugin loader and the
                <methodname>addFilterPrefixPath()</methodname> and
                <methodname>addValidatorPrefixPath()</methodname> were added. Also the constant
                <constant>Zend_Filter_Input::INPUT_NAMESPACE</constant> is now deprecated. The
                constants <constant>Zend_Filter_Input::VALIDATOR_NAMESPACE</constant> and
                <constant>Zend_Filter_Input::FILTER_NAMESPACE</constant> are available in releases
                after 1.7.0.
            </para>
        </note>

        <note>
            <para>
                As of version 1.0.4, <constant>Zend_Filter_Input::NAMESPACE</constant>, having
                value <property>namespace</property>, was changed to
                <constant>Zend_Filter_Input::INPUT_NAMESPACE</constant>, having value
                <property>inputNamespace</property>, in order to comply with the
                <acronym>PHP</acronym> 5.3 reservation of the keyword
                <property>namespace</property>.
            </para>
        </note>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
