       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 $opt->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:             return mb_strlen( $val ) < $min ?
     636:                 $opts->message() :
     637:                 true;
     638:         };
     639:     }
     640:
     641:
     642:     /**
     643:      * Validate a string does not exceed a maximum length.
     644:      *
     645:      *  @param string $val The value to check for validity
     646:      *  @param string[] $data The full data set submitted
     647:      *  @param int|array $opts Validation options. The additional option of
     648:      *    `max` is available for this method to indicate the maximum string
     649:      *    length. If only the default validation options are required, this
     650:      *    parameter can be given as an integer value, which will be used as the
     651:      *    maximum string length.
     652:      *  @param array $host Host information
     653:      *  @return string|true true if the value is valid, a string with an error
     654:      *    message otherwise.
     655:      */
     656:     public static function maxLen( $max, $cfg=null ) {
     657:         $opts = ValidateOptions::select( $cfg );
     658:
     659:         return function ( $val, $data, $field, $host ) use ( $max, $opts ) {
     660:             $common = Validate::_common( $val, $opts );
     661:
     662:             if ( $common !== null ) {
     663:                 return $common === false ?
     664:                     $opts->message() :
     665:                     $common;
     666:             }
     667:
     668:             return mb_strlen( $val ) > $max ?
     669:                 $opts->message() :
     670:                 true;
     671:         };
     672:     }
     673:
     674:     /**
     675:      * Require a string with a certain minimum or maximum number of characters.
     676:      *
     677:      *  @param string $val The value to check for validity
     678:      *  @param string[] $data The full data set submitted
     679:      *  @param int|array $opts Validation options. The additional options of
     680:      *    `min` and `max` are available for this method to indicate the minimum
     681:      *    and maximum string lengths, respectively.
     682:      *  @param array $host Host information
     683:      *  @return string|true true if the value is valid, a string with an error
     684:      *    message otherwise.
     685:      */
     686:     public static function minMaxLen( $min, $max, $cfg=null ) {
     687:         $opts = ValidateOptions::select( $cfg );
     688:
     689:         return function ( $val, $data, $field, $host ) use ( $opts, $min, $max ) {
     690:             $common = Validate::_common( $val, $opts );
     691:
     692:             if ( $common !== null ) {
     693:                 return $common === false ?
     694:                     $opts->message() :
     695:                     $common;
     696:             }
     697:
     698:             $fn = Validate::minLen( $min, $opts );
     699:             $res = $fn( $val, $data, $field, $host );
     700:
     701:             if ( $res !== true ) {
     702:                 return $res;
     703:             }
     704:
     705:             $fn = Validate::maxLen( $max, $opts );
     706:             $res = $fn( $val, $data, $field, $host );
     707:
     708:             if ( $res !== true ) {
     709:                 return $res;
     710:             }
     711:
     712:             return true;
     713:         };
     714:     }
     715:
     716:
     717:     /**
     718:      * Validate as an IP address.
     719:      *
     720:      *  @param string $val The value to check for validity
     721:      *  @param string[] $data The full data set submitted
     722:      *  @param array $opts Validation options. No additional options are
     723:      *    available or required for this validation method.
     724:      *  @param array $host Host information
     725:      *  @return string|true true if the value is valid, a string with an error
     726:      *    message otherwise.
     727:      */
     728:     public static function ip( $cfg=null ) {
     729:         $opts = ValidateOptions::select( $cfg );
     730:
     731:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     732:             $common = Validate::_common( $val, $opts );
     733:
     734:             if ( $common !== null ) {
     735:                 return $common === false ?
     736:                     $opts->message() :
     737:                     $common;
     738:             }
     739:
     740:             return filter_var($val, FILTER_VALIDATE_IP) !== false ?
     741:                 true :
     742:                 $opts->message();
     743:         };
     744:     }
     745:
     746:
     747:     /**
     748:      * Validate as an URL address.
     749:      *
     750:      *  @param string $val The value to check for validity
     751:      *  @param string[] $data The full data set submitted
     752:      *  @param array $opts Validation options. No additional options are
     753:      *    available or required for this validation method.
     754:      *  @param array $host Host information
     755:      *  @return string|true true if the value is valid, a string with an error
     756:      *    message otherwise.
     757:      */
     758:     public static function url( $cfg=null ) {
     759:         $opts = ValidateOptions::select( $cfg );
     760:
     761:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     762:             $common = Validate::_common( $val, $opts );
     763:
     764:             if ( $common !== null ) {
     765:                 return $common === false ?
     766:                     $opts->message() :
     767:                     $common;
     768:             }
     769:
     770:             return filter_var($val, FILTER_VALIDATE_URL) !== false ?
     771:                 true :
     772:                 $opts->message();
     773:         };
     774:     }
     775:
     776:
     777:     /**
     778:      * Check if string could contain an XSS attack string
     779:      *
     780:      *  @param string $val The value to check for validity
     781:      *  @param string[] $data The full data set submitted
     782:      *  @param int|array $opts Validation options. The additional options of
     783:      *    `db` - database connection object, `table` - database table to use and
     784:      *    `column` - the column to check this value against as value, are also
     785:      *    available. These options are not required and if not given are
     786:      *    automatically derived from the Editor and Field instances.
     787:      *  @param array $host Host information
     788:      *  @return string|true true if the value is valid, a string with an error
     789:      *    message otherwise.
     790:      */
     791:     public static function xss ( $cfg=null ) {
     792:         $opts = ValidateOptions::select( $cfg );
     793:
     794:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     795:             $common = Validate::_common( $val, $opts );
     796:
     797:             if ( $common !== null ) {
     798:                 return $common === false ?
     799:                     $opts->message() :
     800:                     $common;
     801:             }
     802:
     803:             return $field->xssSafety( $val ) != $val ?
     804:                 $opts->message() :
     805:                 true;
     806:         };
     807:     }
     808:
     809:
     810:     /**
     811:      * Confirm that the value submitted is in a list of allowable values
     812:      *
     813:      *  @param string $val The value to check for validity
     814:      *  @param string[] $data The full data set submitted
     815:      *  @param int|array $opts Validation options. The additional options of
     816:      *    `db` - database connection object, `table` - database table to use and
     817:      *    `column` - the column to check this value against as value, are also
     818:      *    available. These options are not required and if not given are
     819:      *    automatically derived from the Editor and Field instances.
     820:      *  @param array $host Host information
     821:      *  @return string|true true if the value is valid, a string with an error
     822:      *    message otherwise.
     823:      */
     824:     public static function values( $values, $cfg=null ) {
     825:         $opts = ValidateOptions::select( $cfg );
     826:
     827:         return function ( $val, $data, $field, $host ) use ( $values, $opts ) {
     828:             $common = Validate::_common( $val, $opts );
     829:
     830:             if ( $common !== null ) {
     831:                 return $common === false ?
     832:                     $opts->message() :
     833:                     $common;
     834:             }
     835:
     836:             return in_array($val, $values) ?
     837:                 true :
     838:                 $opts->message();
     839:         };
     840:     }
     841:
     842:
     843:     /**
     844:      * Check if there are any tags in the submitted value
     845:      *
     846:      *  @param string $val The value to check for validity
     847:      *  @param string[] $data The full data set submitted
     848:      *  @param int|array $opts Validation options. The additional options of
     849:      *    `db` - database connection object, `table` - database table to use and
     850:      *    `column` - the column to check this value against as value, are also
     851:      *    available. These options are not required and if not given are
     852:      *    automatically derived from the Editor and Field instances.
     853:      *  @param array $host Host information
     854:      *  @return string|true true if the value is valid, a string with an error
     855:      *    message otherwise.
     856:      */
     857:     public static function noTags ( $cfg=null ) {
     858:         $opts = ValidateOptions::select( $cfg );
     859:
     860:         return function ( $val, $data, $field, $host ) use ( $opts ) {
     861:             $common = Validate::_common( $val, $opts );
     862:
     863:             if ( $common !== null ) {
     864:                 return $common === false ?
     865:                     $opts->message() :
     866:                     $common;
     867:             }
     868:
     869:             return strip_tags( $val ) != $val ?
     870:                 $opts->message() :
     871:                 true;
     872:         };
     873:     }
     874:
     875:
     876:
     877:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     878:      * Date validation methods
     879:      */
     880:
     881:     /**
     882:      * Check that a valid date input is given
     883:      *
     884:      *  @param string $val The value to check for validity
     885:      *  @param string[] $data The full data set submitted
     886:      *  @param array|string $opts If given as a string, then $opts is the date
     887:      *    format to check the validity of. If given as an array, then the
     888:      *    date format is in the 'format' parameter, and the return error
     889:      *    message in the 'message' parameter.
     890:      *  @param array $host Host information
     891:      *  @return string|true true if the value is valid, a string with an error
     892:      *    message otherwise.
     893:      */
     894:     public static function dateFormat( $format, $cfg=null ) {
     895:         $opts = ValidateOptions::select( $cfg );
     896:
     897:         return function ( $val, $data, $field, $host ) use ( $format, $opts ) {
     898:             $common = Validate::_common( $val, $opts );
     899:
     900:             if ( $common !== null ) {
     901:                 return $common === false ?
     902:                     $opts->message() :
     903:                     $common;
     904:             }
     905:
     906:             $formatCreate = substr($format, 0, 1) !== '!' ?
     907:                 '!'.$format :
     908:                 $format;
     909:
     910:             $date = \DateTime::createFromFormat( $formatCreate, $val );
     911:
     912:             return $date && $date->format( $format ) == $val ?
     913:                 true :
     914:                 $opts->message();
     915:         };
     916:     }
     917:
     918:
     919:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     920:      * Database validation methods
     921:      */
     922:
     923:     /**
     924:      * Check that the given value is unique in the database
     925:      *
     926:      *  @param string $val The value to check for validity
     927:      *  @param string[] $data The full data set submitted
     928:      *  @param int|array $opts Validation options. The additional options of
     929:      *    `db` - database connection object, `table` - database table to use and
     930:      *    `column` - the column to check this value against as value, are also
     931:      *    available. These options are not required and if not given are
     932:      *    automatically derived from the Editor and Field instances.
     933:      *  @param array $host Host information
     934:      *  @return string|true true if the value is valid, a string with an error
     935:      *    message otherwise.
     936:      */
     937:     public static function unique( $cfg=null, $column=null, $table=null, $db=null ) {
     938:         $opts = ValidateOptions::select( $cfg );
     939:
     940:         return function ( $val, $data, $field, $host ) use ( $opts, $column, $table, $db ) {
     941:             $common = Validate::_common( $val, $opts );
     942:
     943:             if ( $common !== null ) {
     944:                 return $common === false ?
     945:                     $opts->message() :
     946:                     $common;
     947:             }
     948:
     949:             $editor = $host['editor'];
     950:
     951:             if ( ! $db ) {
     952:                 $db = $host['db'];
     953:             }
     954:
     955:             if ( ! $table ) {
     956:                 $table = $editor->table(); // Returns an array, but `select` will take an array
     957:             }
     958:
     959:             if ( ! $column ) {
     960:                 $column = $field->dbField();
     961:             }
     962:
     963:             $query = $db
     964:                 ->query( 'select', $table )
     965:                 ->get( $column )
     966:                 ->where( $column, $val );
     967:
     968:             // If doing an edit, then we need to also discount the current row,
     969:             // since it is of course already validly unique
     970:             if ( $host['action'] === 'edit' ) {
     971:                 $cond = $editor->pkeyToArray( $host['id'], true );
     972:                 $query->where( $cond, null, '!=' );
     973:             }
     974:
     975:             $res = $query->exec();
     976:
     977:             return $res->count() === 0 ?
     978:                 true :
     979:                 $opts->message();
     980:         };
     981:     }
     982:
     983:     /**
     984:      * Check that the given value is a value that is available in a database -
     985:      * i.e. a join primary key. This will attempt to automatically use the table
     986:      * name and value column from the field's `options` method (under the
     987:      * assumption that it will typically be used with a joined field), but the
     988:      * table and field can also be specified via the options.
     989:      *
     990:      *  @param string $val The value to check for validity
     991:      *  @param string[] $data The full data set submitted
     992:      *  @param int|array $opts Validation options. The additional options of
     993:      *    `db` - database connection object, `table` - database table to use and
     994:      *    `column` - the column to check this value against as value, are also
     995:      *    available. These options are not required and if not given are
     996:      *    automatically derived from the Editor and Field instances.
     997:      *  @param array $host Host information
     998:      *  @return string|true true if the value is valid, a string with an error
     999:      *    message otherwise.
    1000:      */
    1001:     public static function dbValues( $cfg=null, $column=null, $table=null, $db=null, $values=array() ) {
    1002:         $opts = ValidateOptions::select( $cfg );
    1003:
    1004:         return function ( $val, $data, $field, $host ) use ( $opts, $column, $table, $db, $values ) {
    1005:             $common = Validate::_common( $val, $opts );
    1006:
    1007:             if ( $common !== null ) {
    1008:                 return $common === false ?
    1009:                     $opts->message() :
    1010:                     $common;
    1011:             }
    1012:
    1013:             // Allow local values to be defined - for example null
    1014:             if ( in_array($val, $values) ) {
    1015:                 return true;
    1016:             }
    1017:
    1018:             $editor = $host['editor'];
    1019:             $options = $field->options();
    1020:
    1021:             if ( ! $db ) {
    1022:                 $db = $host['db'];
    1023:             }
    1024:
    1025:             if ( ! $table ) {
    1026:                 $table = $options->table(); // Returns an array, but `select` will take an array
    1027:             }
    1028:
    1029:             if ( ! $column ) {
    1030:                 $column = $options->value();
    1031:             }
    1032:
    1033:             if ( ! $table ) {
    1034:                 throw new \Exception('Table for database value check is not defined for field '.$field->name());
    1035:             }
    1036:
    1037:             if ( ! $column ) {
    1038:                 throw new \Exception('Value column for database value check is not defined for field '.$field->name());
    1039:             }
    1040:
    1041:             // Try / catch in case the submitted value can't be represented as the
    1042:             // database type (e.g. an empty string as an integer)
    1043:             try {
    1044:                 $count = $db
    1045:                     ->query( 'select', $table )
    1046:                     ->get( $column )
    1047:                     ->where( $column, $val )
    1048:                     ->exec()
    1049:                     ->count();
    1050:
    1051:                 return $count === 0 ?
    1052:                     $opts->message() :
    1053:                     true;
    1054:             }
    1055:             catch (\Exception $e) {
    1056:                 return $opts->message();
    1057:             }
    1058:         };
    1059:     }
    1060:
    1061:
    1062:
    1063:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1064:     * File validation methods
    1065:     */
    1066:     static function fileExtensions ( $extensions, $msg="This file type cannot be uploaded." ) {
    1067:         return function ( $file ) use ( $extensions, $msg ) {
    1068:             $extn = pathinfo($file['name'], PATHINFO_EXTENSION);
    1069:
    1070:             for ( $i=0, $ien=count($extensions) ; $i<$ien ; $i++ ) {
    1071:                 if ( strtolower( $extn ) === strtolower( $extensions[$i] ) ) {
    1072:                     return true;
    1073:                 }
    1074:             }
    1075:
    1076:             return $msg;
    1077:         };
    1078:     }
    1079:
    1080:     static function fileSize ( $size, $msg="Uploaded file is too large." ) {
    1081:         return function ( $file ) use ( $size, $msg ) {
    1082:             return $file['size'] > $size ?
    1083:                 $msg :
    1084:                 true;
    1085:         };
    1086:     }
    1087:
    1088:
    1089:
    1090:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1091:     * Mjoin validation methods
    1092:     */
    1093:     static function mjoinMinCount ( $count, $msg="Too few items." ) {
    1094:         return function ( $action, $values ) use ( $count, $msg ) {
    1095:             if ( $action === 'create' || $action === 'edit' ) {
    1096:                 return count($values) < $count ?
    1097:                     $msg :
    1098:                     true;
    1099:             }
    1100:             return true;
    1101:         };
    1102:     }
    1103:
    1104:     static function mjoinMaxCount ( $count, $msg="Too many items." ) {
    1105:         return function ( $action, $values ) use ( $count, $msg ) {
    1106:             if ( $action === 'create' || $action === 'edit' ) {
    1107:                 return count($values) > $count ?
    1108:                     $msg :
    1109:                     true;
    1110:             }
    1111:             return true;
    1112:         };
    1113:     }
    1114:
    1115:
    1116:     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1117:      * Internal functions
    1118:      * These legacy methods are for backwards compatibility with the old way of
    1119:      * using the validation methods. They basically do argument swapping.
    1120:      */
    1121:
    1122:     /**
    1123:      * @internal
    1124:      */
    1125:     static function noneLegacy( $legacyOpts ) {
    1126:         return Validate::none();
    1127:     }
    1128:
    1129:     /**
    1130:      * @internal
    1131:      */
    1132:     static function basicLegacy( $legacyOpts ) {
    1133:         $cfg = Validate::_extend( $legacyOpts, null, array() );
    1134:         $opts = Validate::_commonLegacy( $cfg );
    1135:
    1136:         return Validate::required( $opts );
    1137:     }
    1138:
    1139:     /**
    1140:      * @internal
    1141:      */
    1142:     static function requiredLegacy( $legacyOpts ) {
    1143:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1144:             'message' => "This field is required."
    1145:         ) );
    1146:         $opts = Validate::_commonLegacy( $cfg );
    1147:
    1148:         return Validate::required( $opts );
    1149:     }
    1150:
    1151:     /**
    1152:      * @internal
    1153:      */
    1154:     static function notEmptyLegacy( $legacyOpts ) {
    1155:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1156:             'message' => "This field is required."
    1157:         ) );
    1158:         $opts = Validate::_commonLegacy( $cfg );
    1159:
    1160:         return Validate::notEmpty( $opts );
    1161:     }
    1162:
    1163:     /**
    1164:      * @internal
    1165:      */
    1166:     static function booleanLegacy( $legacyOpts ) {
    1167:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1168:             'message' => "Please enter true or false."
    1169:         ) );
    1170:         $opts = Validate::_commonLegacy( $cfg );
    1171:
    1172:         return Validate::notEmpty( $opts );
    1173:     }
    1174:
    1175:     /**
    1176:      * @internal
    1177:      */
    1178:     static function numericLegacy( $legacyOpts ) {
    1179:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1180:             'message' => "This input must be given as a number."
    1181:         ) );
    1182:         $opts = Validate::_commonLegacy( $cfg );
    1183:
    1184:         return isset( $legacyOpts['decimal'] ) ?
    1185:             Validate::numeric( $legacyOpts['decimal'], $opts ) :
    1186:             Validate::numeric( '.', $opts );
    1187:     }
    1188:
    1189:     /**
    1190:      * @internal
    1191:      */
    1192:     static function minNumLegacy( $legacyOpts ) {
    1193:         $min = is_array($legacyOpts) ? $legacyOpts['min'] : $legacyOpts;
    1194:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1195:             'message' => "Number is too small, must be ".$min." or larger."
    1196:         ) );
    1197:         $opts = Validate::_commonLegacy( $cfg );
    1198:
    1199:         return isset( $legacyOpts['decimal'] ) ?
    1200:             Validate::minNum( $min, $legacyOpts['decimal'], $opts ) :
    1201:             Validate::minNum( $min, '.', $opts );
    1202:     }
    1203:
    1204:     /**
    1205:      * @internal
    1206:      */
    1207:     static function maxNumLegacy( $legacyOpts ) {
    1208:         $max = is_array($legacyOpts) ? $legacyOpts['max'] : $legacyOpts;
    1209:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1210:             'message' => "Number is too large, must be ".$max." or smaller."
    1211:         ) );
    1212:         $opts = Validate::_commonLegacy( $cfg );
    1213:
    1214:         return isset( $legacyOpts['decimal'] ) ?
    1215:             Validate::maxNum( $max, $legacyOpts['decimal'], $opts ) :
    1216:             Validate::maxNum( $max, '.', $opts );
    1217:     }
    1218:
    1219:     /**
    1220:      * @internal
    1221:      */
    1222:     static function minMaxNumLegacy( $legacyOpts ) {
    1223:         $min = $legacyOpts['min'];
    1224:         $max = $legacyOpts['max'];
    1225:         $cfg = Validate::_extend( $legacyOpts, null, array() );
    1226:         $opts = Validate::_commonLegacy( $cfg );
    1227:
    1228:         return isset( $legacyOpts['decimal'] ) ?
    1229:             Validate::minMaxNum( $min, $max, $legacyOpts['decimal'], $opts ) :
    1230:             Validate::minMaxNum( $min, $max, '.', $opts );
    1231:     }
    1232:
    1233:     /**
    1234:      * @internal
    1235:      */
    1236:     static function emailLegacy( $legacyOpts ) {
    1237:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1238:             'message' => "Please enter a valid e-mail address."
    1239:         ) );
    1240:         $opts = Validate::_commonLegacy( $cfg );
    1241:
    1242:         return Validate::email( $opts );
    1243:     }
    1244:
    1245:     /**
    1246:      * @internal
    1247:      */
    1248:     static function minLenLegacy( $legacyOpts ) {
    1249:         $min = is_array($legacyOpts) ? $legacyOpts['min'] : $legacyOpts;
    1250:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1251:             'message' => "The input is too short. ".$min." characters required."
    1252:         ) );
    1253:         $opts = Validate::_commonLegacy( $cfg );
    1254:
    1255:         return Validate::minLen( $min, $opts );
    1256:     }
    1257:
    1258:     /**
    1259:      * @internal
    1260:      */
    1261:     static function maxLenLegacy( $legacyOpts ) {
    1262:         $max = is_array($legacyOpts) ? $legacyOpts['max'] : $legacyOpts;
    1263:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1264:             'message' => "The input is too long. ".$max." characters maximum."
    1265:         ) );
    1266:         $opts = Validate::_commonLegacy( $cfg );
    1267:
    1268:         return Validate::maxLen( $max, $opts );
    1269:     }
    1270:
    1271:     /**
    1272:      * @internal
    1273:      */
    1274:     static function minMaxLenLegacy( $legacyOpts ) {
    1275:         $min = $legacyOpts['min'];
    1276:         $max = $legacyOpts['max'];
    1277:         $cfg = Validate::_extend( $legacyOpts, null, array() );
    1278:         $opts = Validate::_commonLegacy( $cfg );
    1279:
    1280:         return Validate::minMaxLen( $min, $max, $opts );
    1281:     }
    1282:
    1283:     /**
    1284:      * @internal
    1285:      */
    1286:     static function ipLegacy( $legacyOpts ) {
    1287:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1288:             'message' => "Please enter a valid IP address."
    1289:         ) );
    1290:         $opts = Validate::_commonLegacy( $cfg );
    1291:
    1292:         return Validate::ip( $opts );
    1293:     }
    1294:
    1295:     /**
    1296:      * @internal
    1297:      */
    1298:     static function urlLegacy( $legacyOpts ) {
    1299:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1300:             'message' => "Please enter a valid URL."
    1301:         ) );
    1302:         $opts = Validate::_commonLegacy( $cfg );
    1303:
    1304:         return Validate::url( $opts );
    1305:     }
    1306:
    1307:     /**
    1308:      * @internal
    1309:      */
    1310:     static function xssLegacy( $legacyOpts ) {
    1311:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1312:             'message' => "This field contains potentially unsafe data."
    1313:         ) );
    1314:         $opts = Validate::_commonLegacy( $cfg );
    1315:
    1316:         return Validate::xss( $opts );
    1317:     }
    1318:
    1319:     /**
    1320:      * @internal
    1321:      */
    1322:     static function valuesLegacy( $legacyOpts ) {
    1323:         $values = isset($legacyOpts['valid']) ? $legacyOpts['valid'] : $legacyOpts;
    1324:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1325:             'message' => "This value is not valid."
    1326:         ) );
    1327:         $opts = Validate::_commonLegacy( $cfg );
    1328:
    1329:         return Validate::values( $values, $opts );
    1330:     }
    1331:
    1332:     /**
    1333:      * @internal
    1334:      */
    1335:     static function noTagsLegacy( $legacyOpts ) {
    1336:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1337:             'message' => "This field may not contain HTML."
    1338:         ) );
    1339:         $opts = Validate::_commonLegacy( $cfg );
    1340:
    1341:         return Validate::noTags( $opts );
    1342:     }
    1343:
    1344:     /**
    1345:      * @internal
    1346:      */
    1347:     static function dateFormatLegacy( $legacyOpts ) {
    1348:         $format = is_array($legacyOpts) ? $legacyOpts['format'] : $legacyOpts;
    1349:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1350:             'message' => "Date is not in the expected format."
    1351:         ) );
    1352:         $opts = Validate::_commonLegacy( $cfg );
    1353:
    1354:         return Validate::dateFormat( $format, $opts );
    1355:     }
    1356:
    1357:     /**
    1358:      * @internal
    1359:      */
    1360:     static function uniqueLegacy( $legacyOpts ) {
    1361:         $table =  isset( $legacyOpts['table'] )  ? $legacyOpts['table']  : null;
    1362:         $column = isset( $legacyOpts['column'] ) ? $legacyOpts['column'] : null;
    1363:         $db =     isset( $legacyOpts['db'] )     ? $legacyOpts['db']     : null;
    1364:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1365:             'message' => "This field must have a unique value."
    1366:         ) );
    1367:         $opts = Validate::_commonLegacy( $cfg );
    1368:
    1369:         return Validate::unique( $opts, $column, $table, $db );
    1370:     }
    1371:
    1372:     /**
    1373:      * @internal
    1374:      */
    1375:     static function dbValuesLegacy( $legacyOpts ) {
    1376:         $table =  isset( $legacyOpts['table'] )  ? $legacyOpts['table']  : null;
    1377:         $column = isset( $legacyOpts['column'] ) ? $legacyOpts['column'] : null;
    1378:         $db =     isset( $legacyOpts['db'] )     ? $legacyOpts['db']     : null;
    1379:         $values = isset( $legacyOpts['values'] ) ? $legacyOpts['values'] : array();
    1380:         $cfg = Validate::_extend( $legacyOpts, null, array(
    1381:             'message' => "This value is not valid."
    1382:         ) );
    1383:         $opts = Validate::_commonLegacy( $cfg );
    1384:
    1385:         return Validate::dbValues( $opts, $column, $table, $db, $values );
    1386:     }
    1387: }
    1388:
    1389: