/lib/Controller/Validator/Basic.php
PHP | 1123 lines | 832 code | 117 blank | 174 comment | 58 complexity | c320e8cb096d1f967f9c3bb1e7b2bb8b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
- <?php
- class Controller_Validator_Basic extends Controller_Validator_Abstract
- {
- public function init()
- {
- parent::init();
- $this->alias = array_merge(
- $this->alias,
- array(
- 'same' => 'eq',
- 'different' => 'ne',
- )
- );
- }
- /* \section Value Test Rules: General */
- public function rule_required($a)
- {
- if ($a === '' || $a === false || $a === null) {
- return $this->fail('must not be empty');
- }
- }
- public function rule_len($a)
- {
- if (!is_string($a)) {
- return $this->fail('must be a string');
- }
- $this->prefix = 'length of ';
- return strlen($a);
- }
- /**
- * Requires a regex pattern as the
- * next rule in the chain.
- *
- * Please give your rule a custom error message.
- */
- public function rule_regex($a)
- {
- $opt = array();
- $rule = $this->pullRule();
- if ($rule[0] != '/') {
- $rule = '/^'.$rule.'*$/';
- }
- $opt['regexp'] = $rule;
- if (!filter_var($a, FILTER_VALIDATE_REGEXP, ['options' => $opt])) {
- return $this->fail('does not match the pattern');
- }
- }
- /* \section Value Test Rules: Value Lists */
- /**
- * Checks that value is in the list provided.
- * Syntax: |in|foo,bar,foobar.
- */
- public function rule_in($a)
- {
- $vals = $this->prep_in_vals($a);
- if (!in_array($a, $vals)) {
- return $this->fail('has an invalid value');
- }
- }
- /**
- * Checks that value is not in the list provided.
- * Syntax: |not_in|foo,bar,foobar.
- */
- public function rule_not_in($a)
- {
- $vals = $this->prep_in_vals($a);
- if (in_array($a, $vals)) {
- return $this->fail('has an invalid value');
- }
- }
- /* \section Value Comparison Rules: absolute value */
- /**
- * Inclusive range check.
- *
- * Overloaded: checks value for numbers,
- * string-length for other values.
- *
- * Next 2 rules must specify the min and max
- */
- public function rule_between($a)
- {
- $min = $this->pullRule(true);
- $max = $this->pullRule(true);
- if (is_numeric($a)) {
- if ($a < $min || $a > $max) {
- return $this->fail('must be between {{arg1}} and {{arg2}}', $min, $max);
- }
- } else {
- return $this->fail('Must be a numeric value');
- }
- }
- public function rule_gt($a)
- {
- $target = $this->pullRule(true);
- if ($a <= $target) {
- return $this->fail('must be greater than {{arg1}}', $target);
- }
- return $a;
- }
- public function rule_lt($a)
- {
- $target = $this->pullRule(true);
- if ($a >= $target) {
- return $this->fail('must be less than {{arg1}}', $target);
- }
- return $a;
- }
- public function rule_gte($a)
- {
- $target = $this->pullRule(true);
- if ($a < $target) {
- return $this->fail('must be at least {{arg1}}', $target);
- }
- return $a;
- }
- public function rule_lte($a)
- {
- $target = $this->pullRule(true);
- if ($a > $target) {
- return $this->fail('must be not greater than {{arg1}}', $target);
- }
- return $a;
- }
- public function rule_eq($a)
- {
- $target = $this->pullRule();
- if ($a !== $target) {
- return $this->fail('must be exactly {{arg1}}', $target);
- }
- return $a;
- }
- public function rule_eqf($a)
- {
- $target=$this->pullRule(true);
- if ($a !== $this->get($target)) {
- return $this->fail('must be same as {{arg1}}', $target);
- }
- return $a;
- }
- /* \section Value Test Rules: Numeric */
- /**
- * Checks for int or float.
- */
- public function rule_number($a)
- {
- if (!is_numeric($a)) {
- return $this->fail('must be a number');
- }
- }
- public function rule_decimal($a)
- {
- if (!preg_match('/^[0-9]+\.[0-9]+$/', $a)) {
- return $this->fail('must be a decimal number: eg 12.34');
- }
- }
- public function rule_phone($a)
- {
- if (strlen(preg_replace('/[^0-9]/', '', $a)) < 6) {
- return $this->fail('must contain valid phone number');
- }
- }
- /**
- * Checks for a specific number of
- * decimal places.
- *
- * Arg: int- number of places
- */
- public function rule_decimal_places($a)
- {
- $places = $this->pullRule();
- $pattern = sprintf('/^[0-9]+\.[0-9]{%s}$/', $places);
- if (!preg_match($pattern, $a)) {
- return $this->fail('Must have {{arg1}} decimal places', $places);
- }
- }
- public function rule_int($a)
- {
- if (!preg_match('/^[0-9]*$/', $a)) {
- return $this->fail('Must be an integer: eg 1234');
- }
- }
- /* \section Value Test Rules: String */
- /**
- * Test for A-Za-z.
- */
- public function rule_alpha($a)
- {
- $msg = 'must contain only letters';
- if (!preg_match('/^([A-Za-z])*$/', $a)) {
- return $this->fail($msg);
- }
- }
- /**
- * Test for A-Za-z0-9.
- */
- public function rule_alphanum($a)
- {
- $msg = 'must contain only digits and letters';
- if (!preg_match('/^([a-zA-Z0-9])*$/', $a)) {
- return $this->fail($msg);
- }
- }
- public function rule_type($a)
- {
- $this->prefix = 'type of ';
- return gettype($a);
- }
- public function rule_class($a)
- {
- if (!is_object($a)) {
- return $this->fail('is not an object');
- }
- $this->prefix = 'class of ';
- return get_class($a);
- }
- /* \section Value Test Rules: Boolean */
- /**
- * Validate for true|false|t|f|1|0|yes|no|y|n.
- *
- * Normalizes to lower case
- */
- public function rule_bool($a)
- {
- // We don't use PHP inbuilt test - a bit restrictive
- // Changes PHP true/false to 1, 0
- $a = strtolower($a);
- $vals = array('true', 'false', 't', 'f', 1, 0, 'yes', 'no', 'y', 'n');
- if (!in_array($a, $vals)) {
- return $this->fail('Must be a boolean value');
- }
- }
- /**
- * Validate for true|t|1|yes|y.
- *
- * Normalizes to lower case
- *
- * Useful for 'if' rules
- */
- public function rule_true($a)
- {
- // Changes PHP true to 1
- $a = strtolower($a);
- $vals = array('true', 't', 1, 'yes', 'y');
- if (!in_array($a, $vals)) {
- return $this->fail('Must be true');
- }
- }
- /**
- * Validate for false|f|0|no|n.
- *
- * Normalizes to lower case
- *
- * Useful for 'if' rules
- */
- public function rule_false($a)
- {
- // Changes PHP false to 0
- $a = strtolower($a);
- $vals = array('false', 'f', 0, 'no', 'n');
- if (!in_array($a, $vals)) {
- return $this->fail('Must be false');
- }
- }
- /* \section Value Test Rules: Date & Time */
- /**
- * Validate for ISO date in format YYYY-MM-DD.
- *
- * Also checks for valid month and day values
- */
- public function validate_iso_date($a)
- {
- $date = explode('-', $a);
- $msg = 'Must be date in format: YYYY-MMM-DD';
- if (count($date) != 3) {
- return $this->fail($msg);
- }
- if (strlen($date[0]) !== 4 || strlen($date[1]) !== 2 || strlen($date[2]) !== 2) {
- return $this->fail($msg);
- }
- if (!@checkdate($date[1], $date[2], $date[0])) {
- return $this->fail($msg);
- }
- }
- /**
- * Validate for ISO time.
- *
- * Requires a complete hour:minute:second time with
- * the optional ':' separators.
- *
- * Checks for hh:mm[[:ss][.**..] where * = microseconds
- * Also checks for valid # of hours, mins, secs
- */
- public function rule_iso_time($a)
- {
- $pattern = "/^([0-9]{2}):([0-9]{2})(?::([0-9]{2})(?:(?:\.[0-9]{1,}))?)?$/";
- $msg = 'Must be a valid ISO time';
- if (preg_match($pattern, $a, $matches)) {
- if ($matches[1] > 24) {
- return $this->fail($msg);
- }
- if ($matches[2] > 59) {
- return $this->fail($msg);
- }
- if (isset($matches[3]) && $matches[3] > 59) {
- return $this->fail($msg);
- }
- } else {
- return $this->fail($msg);
- }
- }
- /**
- * Validate ISO datetime in the format:.
- *
- * YYYY-MM-DD hh:mm:ss with optional microseconds
- */
- public function rule_iso_datetime($a)
- {
- $parts = explode(' ', $a);
- $msg = 'Must be a valid ISO datetime';
- if (count($parts) != 2) {
- return $this->fail($msg);
- }
- try {
- $this->rule_iso_date($parts[0]);
- } catch (Exception $e) {
- return $this->fail($msg);
- }
- try {
- $this->rule_iso_time($parts[1]);
- } catch (Exception $e) {
- return $this->fail($msg);
- }
- }
- /**
- * Checks any PHP datetime format:
- * http://www.php.net/manual/en/datetime.formats.date.php.
- */
- public function rule_before($a)
- {
- $time = $this->pullRule();
- if (strtotime($a) >= strtotime($time)) {
- return $this->fail('Must be before {{arg1}}', $time);
- }
- }
- /**
- * Checks any PHP datetime format:
- * http://www.php.net/manual/en/datetime.formats.date.php.
- */
- public function rule_after($a)
- {
- $time = $this->pullRule();
- if (strtotime($a) <= strtotime($time)) {
- return $this->fail('Must be after {{arg1}}', $time);
- }
- }
- /* \section Value Test Rules: Postal, Email & Credit Card */
- public function rule_email($a)
- {
- if (!filter_var($a, FILTER_VALIDATE_EMAIL)) {
- return $this->fail('Must be a valid email address');
- }
- }
- /**
- * Checks for a 5 digit or extended US zip.
- */
- public function rule_zip($a)
- {
- if (!preg_match('/^\d{5}(-\d{4})?$/', $a)) {
- return $this->fail('Must be a valid ZIP code');
- }
- }
- /**
- * Validate for credit card number.
- *
- * Uses the Luhn Mod 10 check
- */
- public function rule_credit_card($a)
- {
- // Card formats keep changing and there is too high a risk
- // of false negatives if we get clever. So we just check it
- // with the Luhn Mod 10 formula
- // Calculate the Luhn check number
- $msg = 'Not a valid card number';
- $sum = 0;
- $alt = false;
- for ($i = strlen($a) - 1; $i >= 0; --$i) {
- $n = substr($a, $i, 1);
- if ($alt) {
- //square n
- $n *= 2;
- if ($n > 9) {
- //calculate remainder
- $n = ($n % 10) + 1;
- }
- }
- $sum += $n;
- $alt = !$alt;
- }
- // If $sum divides exactly by 10 it's valid
- if (!($sum % 10 == 0)) {
- return $this->fail($msg);
- } else {
- // Luhn check seems to return true for any string of 0s
- $stripped = str_replace('0', '', $a);
- if (strlen($stripped) == 0) {
- return $this->fail($msg);
- }
- }
- }
- /**
- * Validate a card "expires end" date.
- */
- public function rule_card_to_date($a)
- {
- $msg = 'Not a valid date';
- if (!$this->card_date_parser($a, 'to')) {
- return $this->fail($msg);
- }
- }
- /**
- * Validate a card "valid from" date.
- */
- public function rule_card_from_date($a)
- {
- $msg = 'Not a valid date';
- if (!$this->card_date_parser($a, 'from')) {
- return $this->fail($msg);
- }
- }
- /* \section Value Conversion Rules: General */
- /**
- * Strips out the characters matched by the
- * pattern in the argument.
- *
- * The pattern should include the pattern delimiter, eg:
- *
- * /my_pattern/
- */
- public function to_strip_regex($a)
- {
- $pattern = $this->pullRule();
- return preg_replace($pattern, '', $a);
- }
- /* \section Value Conversion Rules: Numeric */
- public function rule_to_int($a)
- {
- return (int) $a = preg_replace('/[^0-9]/', '', $a);
- }
- public function rule_to_number($a)
- {
- return (int) $a = preg_replace('/[^0-9\.]/', '', $a);
- }
- public function rule_to_float($a)
- {
- return (int) $a = preg_replace('/[^0-9\.]/', '', $a);
- }
- public function rule_to_digits_and_single_spaces($a)
- {
- $a = preg_replace("/[^\d ]/", '', $a);
- return $this->rule_strip_extra_space($a);
- }
- /* \section Value Conversion Rules: String */
- public function rule_to_trim($a)
- {
- return trim($a);
- }
- public function rule_to_ltrim($a)
- {
- return ltrim($a);
- }
- public function rule_to_rtrim($a)
- {
- return rtrim($a);
- }
- /**
- * Strip out all white space.
- */
- public function rule_to_strip_space($a)
- {
- return preg_replace("/\s/", '', $a);
- }
- /**
- * Reduce sequential whitespaces to a single space.
- */
- public function rule_to_strip_extra_space($a)
- {
- return $this->strip_excess_whitespace($a);
- }
- /**
- * Strip to A-Za-z0-9.
- */
- public function rule_to_alpha($a)
- {
- return preg_replace('/[^a-zA-Z]/', '', $a);
- }
- /**
- * Test for unicode letter characters.
- *
- * Should work even is PCRE compiled
- * without "--enable-unicode-properties".
- */
- public function rule_to_alpha_unicode($a)
- {
- return preg_replace('/(*UTF8)[^\p{L}]/u', '', $a);
- }
- public function rule_to_alpha_num($a)
- {
- return preg_replace('/[^a-zA-Z0-9]/', '', $a);
- }
- public function rule_to_lower($a)
- {
- return strtolower($a);
- }
- public function rule_to_upper($a)
- {
- return $this->mb_str_to_upper($a);
- }
- public function rule_to_upper_words($a)
- {
- return $this->mb_str_to_upper_words($a);
- }
- /* \section Value Conversion Rules: Alphanumeric */
- /**
- * Strip to unicode letter characters and 0-9.
- *
- * Should work even is PCRE compiled
- * without "--enable-unicode-properties".
- */
- public function rule_to_alpha_num_unicode($a)
- {
- return preg_replace('/(*UTF8)[^\p{L}0-9]/u', '', $a);
- }
- public function rule_to_alpha_num_dash($a)
- {
- return preg_replace('/[^a-zA-Z0-9_-]/', '', $a);
- }
- /**
- * Truncates, and adds '...' to
- * end of string.
- *
- * Requires parameter 'length'
- */
- public function rule_to_truncate($a)
- {
- $len = $this->pullRule();
- return $this->mb_truncate($a, $len);
- }
- /**
- * Requires parameters: length,
- * custom string to end of string.
- */
- public function rule_to_truncate_custom($a)
- {
- $len = $this->pullRule();
- $append = $this->pullRule();
- return $this->mb_truncate($a, $len, $append);
- }
- /**
- * Strip to unicode letter characters and 0-9, -, _.
- *
- * Requires PCRE compiled with "--enable-unicode-properties".
- * Most distros these days will offer this
- */
- public function rule_to_alpha_num_dash_unicode($a)
- {
- return preg_replace('/(*UTF8)[^\p{L}0-9_-]/u', '', $a);
- }
- /* \section Value Conversion Rules: Date & Time */
- public function rule_to_iso_date($a)
- {
- $a = preg_replace("/[^T0-9\/\-\(\): ]/", '', $a);
- return $this->rule_iso_date($a);
- }
- /* \section Value Conversion Rules: Data Sanitization */
- public function rule_to_strip_tags($a)
- {
- return strip_tags($a);
- }
- public function rule_to_quote_meta($a)
- {
- return quotemeta($a);
- }
- public function rule_to_add_slashes($a)
- {
- return addslashes($a);
- }
- public function rule_to_strip_slashes($a)
- {
- return stripslashes($a);
- }
- /**
- * Strip out attack characters from names & addresses
- * and other strings where they have no place.
- *
- * Strips: * ^ <> ? ! () | / \ [] + = % ; ~ `
- */
- public function rule_to_strip_nasties($a)
- {
- return preg_replace("|[\*\^<?>!\"\(\)\|\\\\/\[\]\+=#%;~`]|", '', $a);
- }
- /* \section Value Conversion Rules: Phone, Name, Address */
- /**
- * Normalizes, then validates.
- */
- public function rule_to_zip($a)
- {
- // Change 12345 1234 to 12345-1234
- $a = preg_replace('/[^0-9-]/', '', $a);
- $this->rule_zip($a);
- }
- // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
- // PERSONAL NAMES (European style)
- // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
- /**
- * Useful for cleaning up input where you don't want to present
- * an error to the user - eg a checkout where ease of use is
- * more important than accuracy. Can save a lot of re-keying.
- *
- * Some libraries don't clean up names if already in mixed case.
- * Experience shows this isn't very useful, as many users
- * will type mAry, JOSepH etc.
- *
- * Can only be a best guess - but much better than nothing:
- * has been in production for years without any negative
- * customer feedback.
- *
- * Set $is_capitalise_prefix if you want prefixes in upper:
- * Von Trapp vs von Trapp. You would do this to format
- * a last name for use in salutations:
- *
- * Dear Mr Von Trapp
- *
- * Can handle full names, 1st only, middle only, last only.
- *
- * Cleans up extra whitespace.
- */
- public function rule_to_name($name, $is_capitalise_prefix = false)
- {
- /*
- A name can have up to 5 components, space delimited:
- Worst case:
- salutation | forenames | prefix(es) | main name | suffix
- Ms | Jo-Sue Ellen | de la | Mer-Savarin | III
- Rules for forenames
- 1) Capitalise 1st char and after a hyphen.
- Rules for special case prefixes: von, de etc
- 1) Set capitalisation at runtime.
- There seem to be no fixed rules, but
- lower case is commonly used as part of a
- whole name:
- John von Trapp
- While it is normally capitalised as part of
- a salutation:
- Dear Mr Von Trapp
- By default we store in the lower case form.
- Set the param $is_capitalise_prefix to true
- to capitalise.
- 2) In default mode, St is capitalised,
- other prefixes lower cased. We retain user's
- choice of punctuation with St./St
- Rules for main name:
- 1) Capitalise after a hyphen in the main name:
- Smythington-Fenwick
- 2) Capitalise after Mc at start of name -
- this is pretty much a universal rule
- MCDONALD => McDonald
- 3) Unless user has capitalised after the M,
- do NOT capitalise after Mac at start of name:
- - Many Scottish Mac names
- are not capitalised: Macaulay, Macdonald
- - Many non-Scottish names start with Mac:
- eg Macon - we want to avoid "MacOn";
- - The Cpan name modules and some style manuals
- force MacDonald, but this seems to
- create more problems than it solves.
- macrae => Macrae
- 4) Capitalise after O'
- o'grady => O'Grady
- */
- // If name string is empty, bail out
- if (empty($name)) {
- return '';
- }
- // Setup special case prefix lookup list.
- // These are prefixes that are not capitalised.
- // Prefixes which are capitalised such as "St"
- // can be omitted.
- // We omit prefixes that are also common names,
- // such as "Della", "Di" and "Ben"
- $prefixes = array(
- 'ap' => array('upper' => 'Ap', 'lower' => 'ap'),
- 'da' => array('upper' => 'Da', 'lower' => 'da'),
- 'de' => array('upper' => 'De', 'lower' => 'de'),
- 'del' => array('upper' => 'Del', 'lower' => 'del'),
- 'der' => array('upper' => 'Der', 'lower' => 'der'),
- 'du' => array('upper' => 'Du', 'lower' => 'du'),
- 'la' => array('upper' => 'La', 'lower' => 'la'),
- 'le' => array('upper' => 'Le', 'lower' => 'le'),
- 'lo' => array('upper' => 'Lo', 'lower' => 'lo'),
- 'van' => array('upper' => 'Van', 'lower' => 'van'),
- 'von' => array('upper' => 'Von', 'lower' => 'von'),
- );
- // Set up suffix lookup list
- // We preserve user's preferred punctuation: Sr./Sr
- $suffixes = array(
- 'i' => 'I',
- 'ii' => 'II',
- 'iii' => 'III',
- 'iv' => 'IV',
- 'v' => 'V',
- 'vi' => 'VI',
- 'vii' => 'VII',
- 'viii' => 'VIII',
- 'ix' => 'IX',
- 'x' => 'X',
- 'jr.' => 'Jr.',
- 'jr' => 'Jr',
- 'jnr.' => 'Jnr.',
- 'jnr' => 'Jnr',
- 'sr.' => 'Sr.',
- 'sr' => 'Sr',
- 'snr.' => 'Snr.',
- 'snr' => 'Snr',
- '1st' => '1st',
- '2nd' => '2nd',
- '3rd' => '3rd',
- '4th' => '4th',
- '5th' => '5th',
- '6th' => '6th',
- '7th' => '7th',
- '8th' => '8th',
- '9th' => '9th',
- '10th' => '10th',
- '1st.' => '1st.',
- '2nd.' => '2nd.',
- '3rd.' => '3rd.',
- '4th.' => '4th.',
- '5th.' => '5th.',
- '6th.' => '6th.',
- '7th.' => '7th.',
- '8th.' => '8th.',
- '9th.' => '9th.',
- '10th.' => '10th.',
- );
- // Clean out extra whitespace
- $name = $this->strip_excess_whitespace(trim($name));
- // Try to parse into forenames, main name, suffix
- $parts = explode(' ', $name);
- if (count($parts) == 1) {
- // Must be the main name
- $name_main = array_pop($parts);
- $name_fname = false;
- $name_suffix = false;
- } else {
- // We have more than one part to parse
- // Is the last part a suffix?
- // We assume name can have only one suffix
- $part = array_pop($parts);
- $normalised_part = strtolower($part);
- if (array_key_exists($normalised_part, $suffixes)) {
- // Last part is a suffix
- $name_main = array_pop($parts);
- $name_suffix = $suffixes[$normalised_part];
- } else {
- // Last part is the main name
- $name_main = $part;
- $name_suffix = false;
- }
- }
- // Anything left is a salutation, initial or forname
- if (count($parts) > 0) {
- $name_fnames = $parts;
- } else {
- $name_fnames = false;
- }
- // We build the name from first to last:
- $new_name = array();
- // Set case for the forenames
- if ($name_fnames) {
- foreach ($name_fnames as $fname) {
- $parts = array();
- $fname = strtolower($fname);
- // Do hypenated parts separately
- $exploded_fname = explode('-', $fname);
- foreach ($exploded_fname as $part) {
- // If it is one of our special case prefixes
- // we use the appropriate value
- // Else, we capitalise
- if (array_key_exists($part, $prefixes)) {
- if ($is_capitalise_prefix !== false) {
- $parts[] = $prefixes[$part]['upper'];
- } else {
- $parts[] = $prefixes[$part]['lower'];
- }
- } else {
- // It is a normal forename, salutation or initial
- // We capitalise it.
- $parts[] = ucfirst($part);
- }
- }
- $new_name[] = implode('-', $parts);
- }
- }
- // Set case for the main name
- $name_main_original = $name_main;
- $name_main = strtolower($name_main);
- // Do hypenated parts separately
- $exploded_main_original = explode('-', $name_main_original);
- $exploded_main = explode('-', $name_main);
- $parts = array();
- foreach ($exploded_main as $key => $part) {
- $part_original = $exploded_main_original[$key];
- if (substr($part, 0, 2) == 'mc') {
- // Do "Mc"
- // Uppercase the 3rd character
- $a = substr($part, 2);
- $parts[] = 'Mc'.ucfirst($a);
- } elseif (substr($part, 0, 3) == 'mac') {
- // Do "Mac"
- // Lowercase the 3rd character
- // unless user has submitted
- // a correct looking name
- if (preg_match('|^Mac[A-Z][a-z]*$|', $part_original)) {
- $parts[] = $part_original;
- } else {
- $parts[] = ucfirst($part);
- }
- } elseif (substr($part, 0, 2) == "o'") {
- // Do O'
- // Uppercase the 3rd character
- $a = substr($part, 2);
- $parts[] = "O'".ucwords($a);
- } else {
- // It is a plain-jane name
- $parts[] = ucfirst($part);
- }
- }
- $new_name[] = implode('-', $parts);
- if ($name_suffix !== false) {
- $new_name[] = $name_suffix;
- }
- // Assemble the new name
- $output = implode(' ', $new_name);
- return $output;
- }
- /* \section Helper Functions */
- /**
- * Reduce sequential whitespaces to a single space.
- */
- protected function strip_excess_whitespace($a)
- {
- return preg_replace('/\s\s+/', ' ', $a);
- }
- /**
- * Helper for validating card to and from dates.
- */
- protected function card_date_parser($a, $type)
- {
- // Strip out any slash
- $date = str_replace('/', '', $a);
- // Check that we have 4 digits
- if (!preg_match('|^[0-9]{4}$|', $date)) {
- return false;
- }
- $month = substr($date, 0, 2);
- $year = substr($date, 2, 2);
- // Check month is logical
- if ($month > 12) {
- return false;
- }
- $parts = array(date('Y'), date('m'), 1);
- $now_datetime = new DateTime(implode('-', $parts));
- $parts = array('20'.$year, $month, '1');
- $card_datetime = new DateTime(implode('-', $parts));
- $interval = $now_datetime->diff($card_datetime);
- $days = $interval->format('%R%a days');
- if ($type == 'from') {
- // Check from date is older or equal to current month
- if ($days <= 0 && $days > -3650) {
- return true;
- } else {
- return false;
- }
- } elseif ($type == 'to') {
- // Check to date is newer or equal to current month
- if ($days >= 0 && $days < 3650) {
- return true;
- } else {
- return false;
- }
- } else {
- $msg = "Bad date type '$type' in card-date validation";
- throw new Error($msg);
- }
- }
- /**
- * Explode and trim a comma-delmited list
- * for the in and not_in rules.
- */
- protected function prep_in_vals($a)
- {
- $vals = $this->pullRule();
- if (is_array($vals)) {
- return $vals;
- }
- $vals = explode(',', $vals);
- array_walk($vals, function ($val) {
- return trim($val);
- });
- // create_function('&$val', '$val = trim($val);'));
- return $vals;
- }
- }