<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect2 id="zend.validate.set.callback">
    <title>Callback</title>

    <para>
        <classname>Zend_Validate_Callback</classname> allows you to provide a callback with which to
        validate a given value.
    </para>

    <sect3 id="zend.validate.set.callback.options">
        <title>Supported options for Zend_Validate_Callback</title>

        <para>
            The following options are supported for <classname>Zend_Validate_Callback</classname>:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis><property>callback</property></emphasis>: Sets the callback which will
                    be called for the validation.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>options</property></emphasis>: Sets the additional options
                    which will be given to the callback.
                </para>
            </listitem>
        </itemizedlist>
    </sect3>

    <sect3 id="zend.validate.set.callback.basic">
        <title>Basic usage</title>

        <para>
            The simplest usecase is to have a single function and use it as a callback. Let's expect
            we have the following function.
        </para>

        <programlisting language="php"><![CDATA[
function myMethod($value)
{
    // some validation
    return true;
}
]]></programlisting>

        <para>
            To use it within <classname>Zend_Validate_Callback</classname> you just have to call it
            this way:
        </para>

        <programlisting language="php"><![CDATA[
$valid = new Zend_Validate_Callback('myMethod');
if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>
    </sect3>

    <sect3 id="zend.validate.set.callback.closure">
        <title>Usage with closures</title>

        <para>
            <acronym>PHP</acronym> 5.3 introduces <ulink
                url="http://php.net/functions.anonymous">closures</ulink>, which are basically
            self-contained or <emphasis>anonymous</emphasis> functions. <acronym>PHP</acronym>
            considers closures another form of callback, and, as such, may be used with
            <classname>Zend_Validate_Callback</classname>. As an example:
        </para>

        <programlisting language="php"><![CDATA[
$valid = new Zend_Validate_Callback(function($value){
    // some validation
    return true;
});

if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>
    </sect3>

    <sect3 id="zend.validate.set.callback.class">
        <title>Usage with class-based callbacks</title>

        <para>
            Of course it's also possible to use a class method as callback. Let's expect we have
            the following class method:
        </para>

        <programlisting language="php"><![CDATA[
class MyClass
{
    public function myMethod($value)
    {
        // some validation
        return true;
    }
}
]]></programlisting>

        <para>
            The definition of the callback is in this case almost the same. You have just to create
            an instance of the class before the method and create an array describing the callback:
        </para>

        <programlisting language="php"><![CDATA[
$object = new MyClass;
$valid = new Zend_Validate_Callback(array($object, 'myMethod'));
if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>

        <para>
            You may also define a static method as a callback. Consider the following class
            definition and validator usage:
        </para>

        <programlisting language="php"><![CDATA[
class MyClass
{
    public static function test($value)
    {
        // some validation
        return true;
    }
}

$valid = new Zend_Validate_Callback(array('MyClass', 'test'));
if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>

        <para>
            Finally, if you are using <acronym>PHP</acronym> 5.3, you may define the magic method
            <methodname>__invoke()</methodname> in your class. If you do so, simply providing an
            instance of the class as the callback will also work:
        </para>

        <programlisting language="php"><![CDATA[
class MyClass
{
    public function __invoke($value)
    {
        // some validation
        return true;
    }
}

$object = new MyClass();
$valid = new Zend_Validate_Callback($object);
if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>
    </sect3>

    <sect3 id="zend.validate.set.callback.options2">
        <title>Adding options</title>

        <para>
            <classname>Zend_Validate_Callback</classname> also allows the usage of options which
            are provided as additional arguments to the callback.
        </para>

        <para>
            Consider the following class and method definition:
        </para>

        <programlisting language="php"><![CDATA[
class MyClass
{
    function myMethod($value, $option)
    {
        // some validation
        return true;
    }
}
]]></programlisting>

        <para>
            There are two ways to inform the validator of additional options: pass them in the
            constructor, or pass them to the <methodname>setOptions()</methodname> method.
        </para>

        <para>
            To pass them to the constructor, you would need to pass an array containing two keys,
            "callback" and "options":
        </para>

        <programlisting language="php"><![CDATA[
$valid = new Zend_Validate_Callback(array(
    'callback' => array('MyClass', 'myMethod'),
    'options'  => $option,
));

if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>

        <para>
            Otherwise, you may pass them to the validator after instantiation:
        </para>

        <programlisting language="php"><![CDATA[
$valid = new Zend_Validate_Callback(array('MyClass', 'myMethod'));
$valid->setOptions($option);

if ($valid->isValid($input)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>

        <para>
            When there are additional values given to <methodname>isValid()</methodname> then these
            values will be added immediately after <varname>$value</varname>.
        </para>

        <programlisting language="php"><![CDATA[
$valid = new Zend_Validate_Callback(array('MyClass', 'myMethod'));
$valid->setOptions($option);

if ($valid->isValid($input, $additional)) {
    // input appears to be valid
} else {
    // input is invalid
}
]]></programlisting>

        <para>
            When making the call to the callback, the value to be validated will always be passed as
            the first argument to the callback followed by all other values given to
            <methodname>isValid()</methodname>; all other options will follow it. The amount and
            type of options which can be used is not limited.
        </para>
    </sect3>
</sect2>
<!--
vim:se ts=4 sw=4 et:
-->
