       1: <?php
       2: /**
       3:  * DataTables PHP libraries.
       4:  *
       5:  * PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
       6:  *
       7:  *  @author    SpryMedia
       8:  *  @copyright 2012-2014 SpryMedia ( http://sprymedia.co.uk )
       9:  *  @license   http://editor.datatables.net/license DataTables Editor
      10:  *  @link      http://editor.datatables.net
      11:  */
      12:
      13: namespace DataTables\Editor;
      14: if (!defined('DATATABLES')) exit();
      15:
      16: use DataTables\Editor\ValidateOptions;
      17:
      18: /**
      19:  * Validation methods for DataTables Editor fields.
      20:  *
      21:  * These methods will typically be applied through the {@link Field::validator}
      22:  * method and thus the arguments to be passed will be automatically resolved
      23:  * by Editor.
      24:  *
      25:  * The validation methods in this class all take three parameters:
      26:  *
      27:  * 1. Data to be validated
      28:  * 2. Full data from the form (this can be used with a custom validation method
      29:  *    for dependent validation).
      30:  * 3. Validation configuration options.
      31:  *
      32:  * When using the `Validate` class functions with the {@link Field::validator}
      33:  * method, the second parameter passed into {@link Field::validator} is given
      34:  * to the validation functions here as the third parameter. The first and
      35:  * second parameters are automatically resolved by the {@link Field} class.
      36:  *
      37:  * The validation configuration options is an array of options that can be used
      38:  * to customise the validation - for example defining a date format for date
      39:  * validation. Each validation method has the option of defining its own
      40:  * validation options, but all validation methods provide four common options:
      41:  *
      42:  * * `{boolean} optional` - Require the field to be submitted (`false`) or not
      43:  *   (`true` - default). When set to `true` the field does not need to be
      44:  *   included in the list of parameters sent by the client - if set to `false`
      45:  *   then it must be included. This option can be be particularly used in Editor
      46:  *   as Editor will not set a value for fields which have not been submitted -
      47:  *   giving the ability to submit just a partial list of options.
      48:  * * `{boolean} empty` - Allow a field to be empty, i.e. a zero length string -
      49:  *   `''` (`true` - default) or require it to be non-zero length (`false`).
      50:  * * `{boolean} required` - Short-cut for `optional=false` and `empty=false`.
      51:  *   Note that if this option is set the `optional` and `empty` parameters are
      52:  *   automatically set and cannot be overridden by passing in different values.
      53:  * * `{string} message` - Error message shown should validation fail. This
      54:  *   provides complete control over the message shown to the end user, including
      55:  *   internationalisation (i.e. to provide a translation that is not in the
      56:  *   English language).
      57:  *
      58:  *  @example
      59:  *    <code>
      60:  *      // Ensure that a non-empty value is given for a field
      61:  *      Field::inst( 'engine' )->validator( Validate::required() )
      62:  *    </code>
      63:  *
      64:  *  @example
      65:  *    <code>
      66:  *      // Don't require a field to be submitted, but if it is submitted, it
      67:  *      // must be non-empty
      68:  *      Field::inst( 'reg_date' )->validator( Validate::notEmpty() )
      69:  *    </code>
      70:  *
      71:  *  @example
      72:  *    <code>
      73:  *      // Date validation
      74:  *      Field::inst( 'reg_date' )->validator( Validate::dateFormat( 'D, d M y' ) )
      75:  *    </code>
      76:  *
      77:  *  @example
      78:  *    <code>
      79:  *      // Date validation with a custom error message
      80:  *      Field::inst( 'reg_date' )->validator( Validate::dateFormat( 'D, d M y',
      81:  *          ValidateOptions::inst()
      82:  *              ->message( 'Invalid date' )
      83:  *      ) )
      84:  *    </code>
      85:  *
      86:  *  @example
      87:  *    <code>
      88:  *      // Require a non-empty e-mail address
      89:  *      Field::inst( 'reg_date' )->validator( Validate::email( ValidateOptions::inst()
      90:  *        ->empty( false )
      91:  *      ) )
      92:  *    </code>
      93:  *
      94:  *  @example
      95:  *    <code>
      96:  *      // Custom validation - closure
      97:  *      Field::inst( 'engine' )->validator( function($val, $data, $opts) {
      98:  *         if ( ! preg_match( '/^1/', $val ) ) {
      99:  *           return "Value <b>must</b> start with a 1";
     100:  *         }
     101:  *         return true;
     102:  *      } )
     103:  *    </code>
     104:  */
     105: class Validate {
     106:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     107:      * Internal functions
     108:      */
     109:
     110:     /**
     111:      * "Magic" method to automatically apply the required check to any of the
     112:      * static methods simply by adding '_required' or '_empty' to the end of the
     113:      * method's name, depending on if you need the field to be submitted or not.
     114:      *
     115:      * This is retained for backwards compatibility, but the validation options
     116:      * are now the recommended way of indicating that a field is required.
     117:      *
     118:      * @internal
     119:      * @param string $name Function name
     120:      * @param array $arguments Function arguments
     121:      * @return mixed|string
     122:      */
     123:     public static function __callStatic( $name, $arguments ) {
     124:         if ( preg_match( '/_required$/', $name ) ) {
     125:             if ( $arguments[0] === null || $arguments[0] === '' ) {
     126:                 return 'This field is required';
     127:             }
     128:
     129:             return call_user_func_array(
     130:                 __NAMESPACE__.'\Validate::'.str_replace( '_required', '', $name ),
     131:                 $arguments
     132:             );
     133:         }
     134:     }
     135:
     136:
     137:     /**
     138:      * Extend the options from the user function and the validation function
     139:      * with core defaults.
     140:      *
     141:      *  @internal
     142:      */
     143:     public static function _extend( $userOpts, $prop, $fnOpts ) {
     144:         $cfg = array(
     145:             'message'  => 'Input not valid',
     146:             'required' => false,
     147:             'empty'    => true,
     148:             'optional' => true
     149:         );
     150:
     151:         if ( ! is_array( $userOpts ) ) {
     152:             if ( $prop ) {
     153:                 $cfg[ $prop ] = $userOpts;
     154:             }
     155:
     156:             // Not an array, but the non-array case has been handled above, so
     157:             // just an empty array
     158:             $userOpts = array();
     159:         }
     160:
     161:         // Merge into a single array - first array gets priority if there is a
     162:         // key clash, so user first, then function commands and finally the
     163:         // global options
     164:         $cfg = $userOpts + $fnOpts + $cfg;
     165:
     166:         return $cfg;
     167:     }
     168:
     169:
     170:     /**
     171:      * Perform common validation using the configuration parameters
     172:      *
     173:      *  @internal
     174:      */
     175:     public static function _common( $val, $opts ) {
     176:         $optional = $opts->optional();
     177:         $empty    = $opts->allowEmpty();
     178:
     179:         // Error state tests
     180:         if ( ! $optional && $val === null  ) {
     181:             // Value must be given
     182:             return false;
     183:         }
     184:         else if ( $empty === false && $val === '' ) {
     185:             // Value must not be empty
     186:             return false;
     187:         }
     188:
     189:         // Validation passed states
     190:         if ( $optional && $val === null ) {
     191:             return true;
     192:         }
     193:         else if ( $empty === true && $val === '' ) {
     194:             return true;
     195:         }
     196:
     197:         // Have the specific validation function perform its tests
     198:         return null;
     199:     }
     200:
     201:     /**
     202:      * Convert the old style validation parameters into ValidateOptions
     203:      *
     204:      *  @internal
     205:      */
     206:     public static function _commonLegacy( $cfg ) {
     207:         $opts = new ValidateOptions();
     208:
     209:         if ( is_array( $cfg ) ) {
     210:             // `required` is a legacy shortcut for optional=false, empty=false
     211:             if ( isset( $cfg['required'] ) ) {
     212:                 $opts->optional( false );
     213:                 $opts->allowEmpty( false );
     214:             }
     215:
     216:             if ( isset( $cfg['empty'] ) ) {
     217:                 $opts->allowEmpty( $cfg['empty'] );
     218:             }
     219:
     220:             if ( isset( $cfg['message'] ) ) {
     221:                 $opts->message( $cfg['message'] );
     222:             }
     223:
     224:             if ( isset( $cfg['optional'] ) ) {
     225:                 $opts->optional( $cfg['optional'] );
     226:             }
     227:         }
     228:
     229:         return $opts;
     230:     }
     231:
     232:
     233:
     234:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     235:      * Basic validation
     236:      */
     237:
     238:     /**
     239:      * No validation - all inputs are valid.
     240:      *  @return callable Validation function
     241:      */
     242:     public static function none() {
     243:         return function ( $val, $data, $field, $host ) {
     244:             return true;
     245:         };
     246:     }
     247:
     248:
     249:     /**
     250:      * Basic validation - this is used to perform the validation provided by the
     251:      * validation options only. If the validation options pass (e.g. `required`,
     252:      * `empty` and `optional`) then the validation will pass regardless of the
     253:      * actual value.
     254:      *
     255:      * Note that there are two helper short-cut methods that provide the same
     256:      * function as this method, but are slightly shorter:
     257:      *
     258:      * ```
     259:      * // Required:
     260:      * Validate::required()
     261:      *
     262:      * // is the same as
     263:      * Validate::basic( $val, $data, array(
     264:      *   "required" => true
     265:      * );
     266:      * ```
     267:      *
     268:      * ```
     269:      * // Optional, but not empty if given:
     270:      * Validate::notEmpty()
     271:      *
     272:      * // is the same as
     273:      * Validate::basic( $val, $data, array(
     274:      *   "empty" => false
     275:      * );
     276:      * ```
     277:      *
     278:      * @param string $val The value to check for validity
     279:      * @param string[] $data The full data set submitted
     280:      * @param array $opts Validation options. No additional options are
     281:      *    available or required for this validation method.
     282:      * @param array $host Host information
     283:      * @return string|true true if the value is valid, a string with an error
     284:      *    message otherwise.
     285:      */
     286:     static function basic( $cfg=null ) {
     287:         $opts = ValidateOptions::select( $cfg );
     288:
     289:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     290:             $common = Validate::_common( $val, $opts );
     291:
     292:             return $common === false ?
     293:                 $opts->message() :
     294:                 true;
     295:         };
     296:     }
     297:
     298:
     299:     /**
     300:      * Required field - there must be a value and it must be a non-empty value
     301:      *
     302:      * This is a helper short-cut method which is the same as:
     303:      *
     304:      * ```
     305:      * Validate::basic( $val, $data, array(
     306:      *   "required" => true
     307:      * );
     308:      * ```
     309:      *
     310:      *  @param string $val The value to check for validity
     311:      *  @param string[] $data The full data set submitted
     312:      *  @param array $opts Validation options. No additional options are
     313:      *    available or required for this validation method.
     314:      * @param array $host Host information
     315:      *  @return string|true true if the value is valid, a string with an error
     316:      *    message otherwise.
     317:      */
     318:     static function required( $cfg=null ) {
     319:         $opts = ValidateOptions::select( $cfg );
     320:         $opts->allowEmpty( false );
     321:         $opts->optional( false );
     322:
     323:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     324:             $common = Validate::_common( $val, $opts );
     325:
     326:             return $common === false ?
     327:                 $opts->message() :
     328:                 true;
     329:         };
     330:     }
     331:
     332:
     333:     /**
     334:      * Optional field, but if given there must be a non-empty value
     335:      *
     336:      * This is a helper short-cut method which is the same as:
     337:      *
     338:      * ```
     339:      * Validate::basic( $val, $data, array(
     340:      *   "empty" => false
     341:      * );
     342:      * ```
     343:      *
     344:      *  @param ValidateOptions $cfg Validation options
     345:      *  @return callable Validation function
     346:      */
     347:     static function notEmpty( $cfg=null ) {
     348:         $opts = ValidateOptions::select( $cfg );
     349:         $opts->allowEmpty( false );
     350:
     351:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     352:             $common = Validate::_common( $val, $opts );
     353:
     354:             return $common === false ?
     355:                 $opts->message() :
     356:                 true;
     357:         };
     358:     }
     359:
     360:
     361:     /**
     362:      * Validate an input as a boolean value.
     363:      *
     364:      *  @param string $val The value to check for validity
     365:      *  @param string[] $data The full data set submitted
     366:      *  @param array $opts Validation options. No additional options are
     367:      *    available or required for this validation method.
     368:      *  @param array $host Host information
     369:      *  @return string|true true if the value is valid, a string with an error
     370:      *    message otherwise.
     371:      */
     372:     public static function boolean( $cfg=null ) {
     373:         $opts = ValidateOptions::select( $cfg );
     374:
     375:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     376:             $common = Validate::_common( $val, $opts );
     377:
     378:             if ( $common !== null ) {
     379:                 return $common === false ?
     380:                     $opts->message() :
     381:                     $common;
     382:             }
     383:
     384:             if ( filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === null ) {
     385:                 return $opts->message();
     386:             }
     387:             return true;
     388:         };
     389:     }
     390:
     391:
     392:
     393:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     394:      * Number validation methods
     395:      */
     396:
     397:     /**
     398:      * Check that any input is numeric.
     399:      *
     400:      *  @param string $val The value to check for validity
     401:      *  @param string[] $data The full data set submitted
     402:      *  @param array $opts Validation options. Additional options:
     403:      *     * `decimal`: is available to indicate what character should be used
     404:      *       as the decimal
     405:      *  @param array $host Host information
     406:      *  @return string|true true if the value is valid, a string with an error
     407:      *    message otherwise.
     408:      */
     409:     public static function numeric ( $decimal=".", $cfg=null ) {
     410:         $opts = ValidateOptions::select( $cfg );
     411:
     412:         return function ( $val, $data, $field, $host ) use ( $opts, $decimal ) {
     413:             $common = Validate::_common( $val, $opts );
     414:
     415:             if ( $common !== null ) {
     416:                 return $common === false ?
     417:                     $opts->message() :
     418:                     $common;
     419:             }
     420:
     421:             if ( $decimal !== '.' ) {
     422:                 $val = str_replace( $decimal, '.', $val );
     423:             }
     424:
     425:             return ! is_numeric( $val ) ?
     426:                 $opts->message() :
     427:                 true;
     428:         };
     429:     }
     430:
     431:     /**
     432:      * Check for a numeric input and that it is greater than a given value.
     433:      *
     434:      *  @param string $val The value to check for validity
     435:      *  @param string[] $data The full data set submitted
     436:      *  @param int|array $opts Validation options. Additional options:
     437:      *     * `min`: indicate the minimum value. If only the default validation
     438:      *       options are required, this parameter can be given as an integer
     439:      *       value, which will be used as the minimum value.
     440:      *     * `decimal`: is available to indicate what character should be used
     441:      *       as the decimal
     442:      *    separator (default '.').
     443:      *  @param array $host Host information
     444:      *  @return string|true true if the value is valid, a string with an error
     445:      *    message otherwise.
     446:      */
     447:     public static function minNum ( $min, $decimal=".", $cfg=null ) {
     448:         $opts = ValidateOptions::select( $cfg );
     449:
     450:         return function ( $val, $data, $field, $host ) use ( $opts, $min, $decimal ) {
     451:             $common = Validate::_common( $val, $opts );
     452:
     453:             if ( $common !== null ) {
     454:                 return $common === false ?
     455:                     $opts->message() :
     456:                     $common;
     457:             }
     458:
     459:             $fn = Validate::numeric( $decimal, $opts );
     460:             $numeric = $fn( $val, $data, $field, $host );
     461:
     462:             if ( $numeric !== true ) {
     463:                 return $numeric;
     464:             }
     465:
     466:             if ( $decimal !== '.' ) {
     467:                 $val = str_replace( $decimal, '.', $val );
     468:             }
     469:
     470:             return $val < $min ?
     471:                 $opts->message() :
     472:                 true;
     473:         };
     474:     }
     475:
     476:     /**
     477:      * Check for a numeric input and that it is less than a given value.
     478:      *
     479:      *  @param string $val The value to check for validity
     480:      *  @param string[] $data The full data set submitted
     481:      *  @param int|array $opts Validation options.
     482:      *     * `max`: indicate the maximum value. If only the default validation
     483:      *       options are required, this parameter can be given as an integer
     484:      *       value, which will be used as the maximum value.
     485:      *     * `decimal`: is available to indicate what character should be used
     486:      *       as the decimal
     487:      *  @param array $host Host information
     488:      *  @return string|true true if the value is valid, a string with an error
     489:      *    message otherwise.
     490:      */
     491:     public static function maxNum ( $max, $decimal=".", $cfg=null ) {
     492:         $opts = ValidateOptions::select( $cfg );
     493:
     494:         return function ( $val, $data, $field, $host ) use ( $opts, $max, $decimal ) {
     495:             $common = Validate::_common( $val, $opts );
     496:
     497:             if ( $common !== null ) {
     498:                 return $common === false ?
     499:                     $opts->message() :
     500:                     $common;
     501:             }
     502:
     503:             $fn = Validate::numeric( $decimal, $opts );
     504:             $numeric = $fn( $val, $data, $field, $host );
     505:
     506:             if ( $numeric !== true ) {
     507:                 return $numeric;
     508:             }
     509:
     510:             if ( $decimal !== '.' ) {
     511:                 $val = str_replace( $decimal, '.', $val );
     512:             }
     513:
     514:             return $val > $max ?
     515:                 $opts->message() :
     516:                 true;
     517:         };
     518:     }
     519:
     520:
     521:     /**
     522:      * Check for a numeric input and that it is both greater and smaller than
     523:      * given numbers.
     524:      *
     525:      *  @param string $val The value to check for validity
     526:      *  @param string[] $data The full data set submitted
     527:      *  @param int|array $opts Validation options. Additional options:
     528:      *     * `min`: indicate the minimum value.
     529:      *     * `max`: indicate the maximum value.
     530:      *     * `decimal`: is available to indicate what character should be used
     531:      *       as the decimal
     532:      *  @param array $host Host information
     533:      *  @return string|true true if the value is valid, a string with an error
     534:      *    message otherwise.
     535:      */
     536:     public static function minMaxNum ( $min, $max, $decimal='.', $cfg=null ) {
     537:         $opts = ValidateOptions::select( $cfg );
     538:
     539:         return function ( $val, $data, $field, $host ) use ( $opts, $min, $max, $decimal ) {
     540:             $common = Validate::_common( $val, $opts );
     541:
     542:             if ( $common !== null ) {
     543:                 return $common === false ?
     544:                     $opts->message() :
     545:                     $common;
     546:             }
     547:
     548:             $fn = Validate::numeric( $decimal, $opts );
     549:             $numeric = $fn( $val, $data, $field, $host );
     550:
     551:             if ( $numeric !== true ) {
     552:                 return $numeric;
     553:             }
     554:
     555:             $fn = Validate::minNum( $min, $decimal, $opts );
     556:             $numeric = $fn( $val, $data, $field, $host );
     557:
     558:             if ( $numeric !== true ) {
     559:                 return $numeric;
     560:             }
     561:
     562:             $fn = Validate::maxNum( $max, $decimal, $opts );
     563:             $numeric = $fn( $val, $data, $field, $host );
     564:
     565:             if ( $numeric !== true ) {
     566:                 return $numeric;
     567:             }
     568:
     569:             return true;
     570:         };
     571:     }
     572:
     573:
     574:
     575:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     576:      * String validation methods
     577:      */
     578:
     579:     /**
     580:      * Validate an input as an e-mail address.
     581:      *
     582:      *  @param string $val The value to check for validity
     583:      *  @param string[] $data The full data set submitted
     584:      *  @param array $opts Validation options. No additional options are
     585:      *    available or required for this validation method.
     586:      *  @param array $host Host information
     587:      *  @return string|true true if the value is valid, a string with an error
     588:      *    message otherwise.
     589:      */
     590:     public static function email( $cfg=null ) {
     591:         $opts = ValidateOptions::select( $cfg );
     592:
     593:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     594:             $common = Validate::_common( $val, $opts );
     595:
     596:             if ( $common !== null ) {
     597:                 return $common === false ?
     598:                     $opts->message() :
     599:                     $common;
     600:             }
     601:
     602:             return filter_var($val, FILTER_VALIDATE_EMAIL) !== false ?
     603:                 true :
     604:                 $opts->message();
     605:         };
     606:     }
     607:
     608:
     609:     /**
     610:      * Validate a string has a minimum length.
     611:      *
     612:      *  @param string $val The value to check for validity
     613:      *  @param string[] $data The full data set submitted
     614:      *  @param int|array $opts Validation options. The additional option of
     615:      *    `min` is available for this method to indicate the minimum string
     616:      *    length. If only the default validation options are required, this
     617:      *    parameter can be given as an integer value, which will be used as the
     618:      *    minimum string length.
     619:      *  @param array $host Host information
     620:      *  @return string|true true if the value is valid, a string with an error
     621:      *    message otherwise.
     622:      */
     623:     public static function minLen( $min, $cfg=null ) {
     624:         $opts = ValidateOptions::select( $cfg );
     625:
     626:         return function ( $val, $data, $field, $host ) use ( $min, $opts ) {
     627:             $common = Validate::_common( $val, $opts );
     628:
     629:             if ( $common !== null ) {
     630:                 return $common === false ?
     631:                     $opts->message() :
     632:                     $common;
     633:             }
     634:
     635:             $strlen = is_callable('mb_strlen') ?
     636:                 'mb_strlen' :
     637:                 'strlen';
     638:
     639:             return $strlen( $val ) < $min ?
     640:                 $opts->message() :
     641:                 true;
     642:         };
     643:     }
     644:
     645:
     646:     /**
     647:      * Validate a string does not exceed a maximum length.
     648:      *
     649:      *  @param string $val The value to check for validity
     650:      *  @param string[] $data The full data set submitted
     651:      *  @param int|array $opts Validation options. The additional option of
     652:      *    `max` is available for this method to indicate the maximum string
     653:      *    length. If only the default validation options are required, this
     654:      *    parameter can be given as an integer value, which will be used as the
     655:      *    maximum string length.
     656:      *  @param array $host Host information
     657:      *  @return string|true true if the value is valid, a string with an error
     658:      *    message otherwise.
     659:      */
     660:     public static function maxLen( $max, $cfg=null ) {
     661:         $opts = ValidateOptions::select( $cfg );
     662:
     663:         return function ( $val, $data, $field, $host ) use ( $max, $opts ) {
     664:             $common = Validate::_common( $val, $opts );
     665:
     666:             if ( $common !== null ) {
     667:                 return $common === false ?
     668:                     $opts->message() :
     669:                     $common;
     670:             }
     671:
     672:             $strlen = is_callable('mb_strlen') ?
     673:                 'mb_strlen' :
     674:                 'strlen';
     675:
     676:             return $strlen( $val ) > $max ?
     677:                 $opts->message() :
     678:                 true;
     679:         };
     680:     }
     681:
     682:     /**
     683:      * Require a string with a certain minimum or maximum number of characters.
     684:      *
     685:      *  @param string $val The value to check for validity
     686:      *  @param string[] $data The full data set submitted
     687:      *  @param int|array $opts Validation options. The additional options of
     688:      *    `min` and `max` are available for this method to indicate the minimum
     689:      *    and maximum string lengths, respectively.
     690:      *  @param array $host Host information
     691:      *  @return string|true true if the value is valid, a string with an error
     692:      *    message otherwise.
     693:      */
     694:     public static function minMaxLen( $min, $max, $cfg=null ) {
     695:         $opts = ValidateOptions::select( $cfg );
     696:
     697:         return function ( $val, $data, $field, $host ) use ( $opts, $min, $max ) {
     698:             $common = Validate::_common( $val, $opts );
     699:
     700:             if ( $common !== null ) {
     701:                 return $common === false ?
     702:                     $opts->message() :
     703:                     $common;
     704:             }
     705:
     706:             $fn = Validate::minLen( $min, $opts );
     707:             $res = $fn( $val, $data, $field, $host );
     708:
     709:             if ( $res !== true ) {
     710:                 return $res;
     711:             }
     712:
     713:             $fn = Validate::maxLen( $max, $opts );
     714:             $res = $fn( $val, $data, $field, $host );
     715:
     716:             if ( $res !== true ) {
     717:                 return $res;
     718:             }
     719:
     720:             return true;
     721:         };
     722:     }
     723:
     724:
     725:     /**
     726:      * Validate as an IP address.
     727:      *
     728:      *  @param string $val The value to check for validity
     729:      *  @param string[] $data The full data set submitted
     730:      *  @param array $opts Validation options. No additional options are
     731:      *    available or required for this validation method.
     732:      *  @param array $host Host information
     733:      *  @return string|true true if the value is valid, a string with an error
     734:      *    message otherwise.
     735:      */
     736:     public static function ip( $cfg=null ) {
     737:         $opts = ValidateOptions::select( $cfg );
     738:
     739:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     740:             $common = Validate::_common( $val, $opts );
     741:
     742:             if ( $common !== null ) {
     743:                 return $common === false ?
     744:                     $opts->message() :
     745:                     $common;
     746:             }
     747:
     748:             return filter_var($val, FILTER_VALIDATE_IP) !== false ?
     749:                 true :
     750:                 $opts->message();
     751:         };
     752:     }
     753:
     754:
     755:     /**
     756:      * Validate as an URL address.
     757:      *
     758:      *  @param string $val The value to check for validity
     759:      *  @param string[] $data The full data set submitted
     760:      *  @param array $opts Validation options. No additional options are
     761:      *    available or required for this validation method.
     762:      *  @param array $host Host information
     763:      *  @return string|true true if the value is valid, a string with an error
     764:      *    message otherwise.
     765:      */
     766:     public static function url( $cfg=null ) {
     767:         $opts = ValidateOptions::select( $cfg );
     768:
     769:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     770:             $common = Validate::_common( $val, $opts );
     771:
     772:             if ( $common !== null ) {
     773:                 return $common === false ?
     774:                     $opts->message() :
     775:                     $common;
     776:             }
     777:
     778:             return filter_var($val, FILTER_VALIDATE_URL) !== false ?
     779:                 true :
     780:                 $opts->message();
     781:         };
     782:     }
     783:
     784:
     785:     /**
     786:      * Check if string could contain an XSS attack string
     787:      *
     788:      *  @param string $val The value to check for validity
     789:      *  @param string[] $data The full data set submitted
     790:      *  @param int|array $opts Validation options. The additional options of
     791:      *    `db` - database connection object, `table` - database table to use and
     792:      *    `column` - the column to check this value against as value, are also
     793:      *    available. These options are not required and if not given are
     794:      *    automatically derived from the Editor and Field instances.
     795:      *  @param array $host Host information
     796:      *  @return string|true true if the value is valid, a string with an error
     797:      *    message otherwise.
     798:      */
     799:     public static function xss ( $cfg=null ) {
     800:         $opts = ValidateOptions::select( $cfg );
     801:
     802:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     803:             $common = Validate::_common( $val, $opts );
     804:
     805:             if ( $common !== null ) {
     806:                 return $common === false ?
     807:                     $opts->message() :
     808:                     $common;
     809:             }
     810:
     811:             return $field->xssSafety( $val ) != $val ?
     812:                 $opts->message() :
     813:                 true;
     814:         };
     815:     }
     816:
     817:
     818:     /**
     819:      * Confirm that the value submitted is in a list of allowable values
     820:      *
     821:      *  @param string $val The value to check for validity
     822:      *  @param string[] $data The full data set submitted
     823:      *  @param int|array $opts Validation options. The additional options of
     824:      *    `db` - database connection object, `table` - database table to use and
     825:      *    `column` - the column to check this value against as value, are also
     826:      *    available. These options are not required and if not given are
     827:      *    automatically derived from the Editor and Field instances.
     828:      *  @param array $host Host information
     829:      *  @return string|true true if the value is valid, a string with an error
     830:      *    message otherwise.
     831:      */
     832:     public static function values( $values, $cfg=null ) {
     833:         $opts = ValidateOptions::select( $cfg );
     834:
     835:         return function ( $val, $data, $field, $host ) use ( $values, $opts ) {
     836:             $common = Validate::_common( $val, $opts );
     837:
     838:             if ( $common !== null ) {
     839:                 return $common === false ?
     840:                     $opts->message() :
     841:                     $common;
     842:             }
     843:
     844:             return in_array($val, $values) ?
     845:                 true :
     846:                 $opts->message();
     847:         };
     848:     }
     849:
     850:
     851:     /**
     852:      * Check if there are any tags in the submitted value
     853:      *
     854:      *  @param string $val The value to check for validity
     855:      *  @param string[] $data The full data set submitted
     856:      *  @param int|array $opts Validation options. The additional options of
     857:      *    `db` - database connection object, `table` - database table to use and
     858:      *    `column` - the column to check this value against as value, are also
     859:      *    available. These options are not required and if not given are
     860:      *    automatically derived from the Editor and Field instances.
     861:      *  @param array $host Host information
     862:      *  @return string|true true if the value is valid, a string with an error
     863:      *    message otherwise.
     864:      */
     865:     public static function noTags ( $cfg=null ) {
     866:         $opts = ValidateOptions::select( $cfg );
     867:
     868:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     869:             $common = Validate::_common( $val, $opts );
     870:
     871:             if ( $common !== null ) {
     872:                 return $common === false ?
     873:                     $opts->message() :
     874:                     $common;
     875:             }
     876:
     877:             return strip_tags( $val ) != $val ?
     878:                 $opts->message() :
     879:                 true;
     880:         };
     881:     }
     882:
     883:
     884:
     885:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     886:      * Date validation methods
     887:      */
     888:
     889:     /**
     890:      * Check that a valid date input is given
     891:      *
     892:      *  @param string $val The value to check for validity
     893:      *  @param string[] $data The full data set submitted
     894:      *  @param array|string $opts If given as a string, then $opts is the date
     895:      *    format to check the validity of. If given as an array, then the
     896:      *    date format is in the 'format' parameter, and the return error
     897:      *    message in the 'message' parameter.
     898:      *  @param array $host Host information
     899:      *  @return string|true true if the value is valid, a string with an error
     900:      *    message otherwise.
     901:      */
     902:     public static function dateFormat( $format, $cfg=null ) {
     903:         $opts = ValidateOptions::select( $cfg );
     904:
     905:         return function ( $val, $data, $field, $host ) use ( $format, $opts ) {
     906:             $common = Validate::_common( $val, $opts );
     907:
     908:             if ( $common !== null ) {
     909:                 return $common === false ?
     910:                     $opts->message() :
     911:                     $common;
     912:             }
     913:
     914:             $formatCreate = substr($format, 0, 1) !== '!' ?
     915:                 '!'.$format :
     916:                 $format;
     917:
     918:             $date = \DateTime::createFromFormat( $formatCreate, $val );
     919:
     920:             return $date && $date->format( $format ) == $val ?
     921:                 true :
     922:                 $opts->message();
     923:         };
     924:     }
     925:
     926:
     927:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     928:      * Database validation methods
     929:      */
     930:
     931:     /**
     932:      * Check that the given value is unique in the database
     933:      *
     934:      *  @param string $val The value to check for validity
     935:      *  @param string[] $data The full data set submitted
     936:      *  @param int|array $opts Validation options. The additional options of
     937:      *    `db` - database connection object, `table` - database table to use and
     938:      *    `column` - the column to check this value against as value, are also
     939:      *    available. These options are not required and if not given are
     940:      *    automatically derived from the Editor and Field instances.
     941:      *  @param array $host Host information
     942:      *  @return string|true true if the value is valid, a string with an error
     943:      *    message otherwise.
     944:      */
     945:     public static function unique( $cfg=null, $column=null, $table=null, $db=null ) {
     946:         $opts = ValidateOptions::select( $cfg );
     947:
     948:         return function ( $val, $data, $field, $host ) use ( $opts, $column, $table, $db ) {
     949:             $common = Validate::_common( $val, $opts );
     950:
     951:             if ( $common !== null ) {
     952:                 return $common === false ?
     953:                     $opts->message() :
     954:                     $common;
     955:             }
     956:
     957:             $editor = $host['editor'];
     958:
     959:             if ( ! $db ) {
     960:                 $db = $host['db'];
     961:             }
     962:
     963:             if ( ! $table ) {
     964:                 $table = $editor->table(); // Returns an array, but `select` will take an array
     965:             }
     966:
     967:             if ( ! $column ) {
     968:                 $column = $field->dbField();
     969:             }
     970:
     971:             $query = $db
     972:                 ->query( 'select', $table )
     973:                 ->get( $column )
     974:                 ->where( $column, $val );
     975:
     976:             // If doing an edit, then we need to also discount the current row,
     977:             // since it is of course already validly unique
     978:             if ( $host['action'] === 'edit' ) {
     979:                 $cond = $editor->pkeyToArray( $host['id'], true );
     980:                 $query->where( $cond, null, '!=' );
     981:             }
     982:
     983:             $res = $query->exec();
     984:
     985:             return $res->count() === 0 ?
     986:                 true :
     987:                 $opts->message();
     988:         };
     989:     }
     990:
     991:     /**
     992:      * Check that the given value is a value that is available in a database -
     993:      * i.e. a join primary key. This will attempt to automatically use the table
     994:      * name and value column from the field's `options` method (under the
     995:      * assumption that it will typically be used with a joined field), but the
     996:      * table and field can also be specified via the options.
     997:      *
     998:      *  @param string $val The value to check for validity
     999:      *  @param string[] $data The full data set submitted
    1000:      *  @param int|array $opts Validation options. The additional options of
    1001:      *    `db` - database connection object, `table` - database table to use and
    1002:      *    `column` - the column to check this value against as value, are also
    1003:      *    available. These options are not required and if not given are
    1004:      *    automatically derived from the Editor and Field instances.
    1005:      *  @param array $host Host information
    1006:      *  @return string|true true if the value is valid, a string with an error
    1007:      *    message otherwise.
    1008:      */
    1009:     public static function dbValues( $cfg=null, $column=null, $table=null, $db=null, $values=array() ) {
    1010:         $opts = ValidateOptions::select( $cfg );
    1011:
    1012:         return function ( $val, $data, $field, $host ) use ( $opts, $column, $table, $db, $values ) {
    1013:             $common = Validate::_common( $val, $opts );
    1014:
    1015:             if ( $common !== null ) {
    1016:                 return $common === false ?
    1017:                     $opts->message() :
    1018:                     $common;
    1019:             }
    1020:
    1021:             // Allow local values to be defined - for example null
    1022:             if ( in_array($val, $values) ) {
    1023:                 return true;
    1024:             }
    1025:
    1026:             $editor = $host['editor'];
    1027:             $options = $field->options();
    1028:
    1029:             if ( ! $db ) {
    1030:                 $db = $host['db'];
    1031:             }
    1032:
    1033:             if ( ! $table ) {
    1034:                 $table = $options->table(); // Returns an array, but `select` will take an array
    1035:             }
    1036:
    1037:             if ( ! $column ) {
    1038:                 $column = $options->value();
    1039:             }
    1040:
    1041:             if ( ! $table ) {
    1042:                 throw new \Exception('Table for database value check is not defined for field '.$field->name());
    1043:             }
    1044:
    1045:             if ( ! $column ) {
    1046:                 throw new \Exception('Value column for database value check is not defined for field '.$field->name());
    1047:             }
    1048:
    1049:             // Try / catch in case the submitted value can't be represented as the
    1050:             // database type (e.g. an empty string as an integer)
    1051:             try {
    1052:                 $count = $db
    1053:                     ->query( 'select', $table )
    1054:                     ->get( $column )
    1055:                     ->where( $column, $val )
    1056:                     ->exec()
    1057:                     ->count();
    1058:
    1059:                 return $count === 0 ?
    1060:                     $opts->message() :
    1061:                     true;
    1062:             }
    1063:             catch (\Exception $e) {
    1064:                 return $opts->message();
    1065:             }
    1066:         };
    1067:     }
    1068:
    1069:
    1070:
    1071:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1072:     * File validation methods
    1073:     */
    1074:     static function fileExtensions ( $extensions, $msg="This file type cannot be uploaded." ) {
    1075:         return function ( $file ) use ( $extensions, $msg ) {
    1076:             $extn = pathinfo($file['name'], PATHINFO_EXTENSION);
    1077:
    1078:             for ( $i=0, $ien=count($extensions) ; $i<$ien ; $i++ ) {
    1079:                 if ( strtolower( $extn ) === strtolower( $extensions[$i] ) ) {
    1080:                     return true;
    1081:                 }
    1082:             }
    1083:
    1084:             return $msg;
    1085:         };
    1086:     }
    1087:
    1088:     static function fileSize ( $size, $msg="Uploaded file is too large." ) {
    1089:         return function ( $file ) use ( $size, $msg ) {
    1090:             return $file['size'] > $size ?
    1091:                 $msg :
    1092:                 true;
    1093:         };
    1094:     }
    1095:
    1096:
    1097:
    1098:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1099:     * Mjoin validation methods
    1100:     */
    1101:     static function mjoinMinCount ( $count, $msg="Too few items." ) {
    1102:         return function ( $editor, $action, $values ) use ( $count, $msg ) {
    1103:             if ( $action === 'create' || $action === 'edit' ) {
    1104:                 return count($values) < $count ?
    1105:                     $msg :
    1106:                     true;
    1107:             }
    1108:             return true;
    1109:         };
    1110:     }
    1111:
    1112:     static function mjoinMaxCount ( $count, $msg="Too many items." ) {
    1113:         return function ( $editor, $action, $values ) use ( $count, $msg ) {
    1114:             if ( $action === 'create' || $action === 'edit' ) {
    1115:                 return count($values) > $count ?
    1116:                     $msg :
    1117:                     true;
    1118:             }
    1119:             return true;
    1120:         };
    1121:     }
    1122:
    1123:
    1124:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1125:      * Internal functions
    1126:      * These legacy methods are for backwards compatibility with the old way of
    1127:      * using the validation methods. They basically do argument swapping.
    1128:      */
    1129:
    1130:     /**
    1131:      * @internal
    1132:      */
    1133:     static function noneLegacy( $legacyOpts ) {
    1134:         return Validate::none();
    1135:     }
    1136:
    1137:     /**
    1138:      * @internal
    1139:      */
    1140:     static function basicLegacy( $legacyOpts ) {
    1141:         $cfg = Validate::_extend( $legacyOpts, null, array() );
    1142:         $opts = Validate::_commonLegacy( $cfg );
    1143:
    1144:         return Validate::required( $opts );
    1145:     }
    1146:
    1147:     /**
    1148:      * @internal
    1149:      */
    1150:     static function requiredLegacy( $legacyOpts ) {
    1151:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1152:             'message' => "This field is required."
    1153:         ) );
    1154:         $opts = Validate::_commonLegacy( $cfg );
    1155:
    1156:         return Validate::required( $opts );
    1157:     }
    1158:
    1159:     /**
    1160:      * @internal
    1161:      */
    1162:     static function notEmptyLegacy( $legacyOpts ) {
    1163:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1164:             'message' => "This field is required."
    1165:         ) );
    1166:         $opts = Validate::_commonLegacy( $cfg );
    1167:
    1168:         return Validate::notEmpty( $opts );
    1169:     }
    1170:
    1171:     /**
    1172:      * @internal
    1173:      */
    1174:     static function booleanLegacy( $legacyOpts ) {
    1175:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1176:             'message' => "Please enter true or false."
    1177:         ) );
    1178:         $opts = Validate::_commonLegacy( $cfg );
    1179:
    1180:         return Validate::notEmpty( $opts );
    1181:     }
    1182:
    1183:     /**
    1184:      * @internal
    1185:      */
    1186:     static function numericLegacy( $legacyOpts ) {
    1187:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1188:             'message' => "This input must be given as a number."
    1189:         ) );
    1190:         $opts = Validate::_commonLegacy( $cfg );
    1191:
    1192:         return isset( $legacyOpts['decimal'] ) ?
    1193:             Validate::numeric( $legacyOpts['decimal'], $opts ) :
    1194:             Validate::numeric( '.', $opts );
    1195:     }
    1196:
    1197:     /**
    1198:      * @internal
    1199:      */
    1200:     static function minNumLegacy( $legacyOpts ) {
    1201:         $min = is_array($legacyOpts) ? $legacyOpts['min'] : $legacyOpts;
    1202:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1203:             'message' => "Number is too small, must be ".$min." or larger."
    1204:         ) );
    1205:         $opts = Validate::_commonLegacy( $cfg );
    1206:
    1207:         return isset( $legacyOpts['decimal'] ) ?
    1208:             Validate::minNum( $min, $legacyOpts['decimal'], $opts ) :
    1209:             Validate::minNum( $min, '.', $opts );
    1210:     }
    1211:
    1212:     /**
    1213:      * @internal
    1214:      */
    1215:     static function maxNumLegacy( $legacyOpts ) {
    1216:         $max = is_array($legacyOpts) ? $legacyOpts['max'] : $legacyOpts;
    1217:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1218:             'message' => "Number is too large, must be ".$max." or smaller."
    1219:         ) );
    1220:         $opts = Validate::_commonLegacy( $cfg );
    1221:
    1222:         return isset( $legacyOpts['decimal'] ) ?
    1223:             Validate::maxNum( $max, $legacyOpts['decimal'], $opts ) :
    1224:             Validate::maxNum( $max, '.', $opts );
    1225:     }
    1226:
    1227:     /**
    1228:      * @internal
    1229:      */
    1230:     static function minMaxNumLegacy( $legacyOpts ) {
    1231:         $min = $legacyOpts['min'];
    1232:         $max = $legacyOpts['max'];
    1233:         $cfg = Validate::_extend( $legacyOpts, null, array() );
    1234:         $opts = Validate::_commonLegacy( $cfg );
    1235:
    1236:         return isset( $legacyOpts['decimal'] ) ?
    1237:             Validate::minMaxNum( $min, $max, $legacyOpts['decimal'], $opts ) :
    1238:             Validate::minMaxNum( $min, $max, '.', $opts );
    1239:     }
    1240:
    1241:     /**
    1242:      * @internal
    1243:      */
    1244:     static function emailLegacy( $legacyOpts ) {
    1245:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1246:             'message' => "Please enter a valid e-mail address."
    1247:         ) );
    1248:         $opts = Validate::_commonLegacy( $cfg );
    1249:
    1250:         return Validate::email( $opts );
    1251:     }
    1252:
    1253:     /**
    1254:      * @internal
    1255:      */
    1256:     static function minLenLegacy( $legacyOpts ) {
    1257:         $min = is_array($legacyOpts) ? $legacyOpts['min'] : $legacyOpts;
    1258:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1259:             'message' => "The input is too short. ".$min." characters required."
    1260:         ) );
    1261:         $opts = Validate::_commonLegacy( $cfg );
    1262:
    1263:         return Validate::minLen( $min, $opts );
    1264:     }
    1265:
    1266:     /**
    1267:      * @internal
    1268:      */
    1269:     static function maxLenLegacy( $legacyOpts ) {
    1270:         $max = is_array($legacyOpts) ? $legacyOpts['max'] : $legacyOpts;
    1271:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1272:             'message' => "The input is too long. ".$max." characters maximum."
    1273:         ) );
    1274:         $opts = Validate::_commonLegacy( $cfg );
    1275:
    1276:         return Validate::maxLen( $max, $opts );
    1277:     }
    1278:
    1279:     /**
    1280:      * @internal
    1281:      */
    1282:     static function minMaxLenLegacy( $legacyOpts ) {
    1283:         $min = $legacyOpts['min'];
    1284:         $max = $legacyOpts['max'];
    1285:         $cfg = Validate::_extend( $legacyOpts, null, array() );
    1286:         $opts = Validate::_commonLegacy( $cfg );
    1287:
    1288:         return Validate::minMaxLen( $min, $max, $opts );
    1289:     }
    1290:
    1291:     /**
    1292:      * @internal
    1293:      */
    1294:     static function ipLegacy( $legacyOpts ) {
    1295:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1296:             'message' => "Please enter a valid IP address."
    1297:         ) );
    1298:         $opts = Validate::_commonLegacy( $cfg );
    1299:
    1300:         return Validate::ip( $opts );
    1301:     }
    1302:
    1303:     /**
    1304:      * @internal
    1305:      */
    1306:     static function urlLegacy( $legacyOpts ) {
    1307:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1308:             'message' => "Please enter a valid URL."
    1309:         ) );
    1310:         $opts = Validate::_commonLegacy( $cfg );
    1311:
    1312:         return Validate::url( $opts );
    1313:     }
    1314:
    1315:     /**
    1316:      * @internal
    1317:      */
    1318:     static function xssLegacy( $legacyOpts ) {
    1319:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1320:             'message' => "This field contains potentially unsafe data."
    1321:         ) );
    1322:         $opts = Validate::_commonLegacy( $cfg );
    1323:
    1324:         return Validate::xss( $opts );
    1325:     }
    1326:
    1327:     /**
    1328:      * @internal
    1329:      */
    1330:     static function valuesLegacy( $legacyOpts ) {
    1331:         $values = isset($legacyOpts['valid']) ? $legacyOpts['valid'] : $legacyOpts;
    1332:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1333:             'message' => "This value is not valid."
    1334:         ) );
    1335:         $opts = Validate::_commonLegacy( $cfg );
    1336:
    1337:         return Validate::values( $values, $opts );
    1338:     }
    1339:
    1340:     /**
    1341:      * @internal
    1342:      */
    1343:     static function noTagsLegacy( $legacyOpts ) {
    1344:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1345:             'message' => "This field may not contain HTML."
    1346:         ) );
    1347:         $opts = Validate::_commonLegacy( $cfg );
    1348:
    1349:         return Validate::noTags( $opts );
    1350:     }
    1351:
    1352:     /**
    1353:      * @internal
    1354:      */
    1355:     static function dateFormatLegacy( $legacyOpts ) {
    1356:         $format = is_array($legacyOpts) ? $legacyOpts['format'] : $legacyOpts;
    1357:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1358:             'message' => "Date is not in the expected format."
    1359:         ) );
    1360:         $opts = Validate::_commonLegacy( $cfg );
    1361:
    1362:         return Validate::dateFormat( $format, $opts );
    1363:     }
    1364:
    1365:     /**
    1366:      * @internal
    1367:      */
    1368:     static function uniqueLegacy( $legacyOpts ) {
    1369:         $table =  isset( $legacyOpts['table'] )  ? $legacyOpts['table']  : null;
    1370:         $column = isset( $legacyOpts['column'] ) ? $legacyOpts['column'] : null;
    1371:         $db =     isset( $legacyOpts['db'] )     ? $legacyOpts['db']     : null;
    1372:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1373:             'message' => "This field must have a unique value."
    1374:         ) );
    1375:         $opts = Validate::_commonLegacy( $cfg );
    1376:
    1377:         return Validate::unique( $opts, $column, $table, $db );
    1378:     }
    1379:
    1380:     /**
    1381:      * @internal
    1382:      */
    1383:     static function dbValuesLegacy( $legacyOpts ) {
    1384:         $table =  isset( $legacyOpts['table'] )  ? $legacyOpts['table']  : null;
    1385:         $column = isset( $legacyOpts['column'] ) ? $legacyOpts['column'] : null;
    1386:         $db =     isset( $legacyOpts['db'] )     ? $legacyOpts['db']     : null;
    1387:         $values = isset( $legacyOpts['values'] ) ? $legacyOpts['values'] : array();
    1388:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1389:             'message' => "This value is not valid."
    1390:         ) );
    1391:         $opts = Validate::_commonLegacy( $cfg );
    1392:
    1393:         return Validate::dbValues( $opts, $column, $table, $db, $values );
    1394:     }
    1395: }
    1396:
    1397: