diff --git a/src/Validation/CaValidation.php b/src/Validation/CaValidation.php index 853877bc..e93a659b 100644 --- a/src/Validation/CaValidation.php +++ b/src/Validation/CaValidation.php @@ -45,7 +45,56 @@ public static function postal($check) */ public static function phone($check) { - throw new NotImplementedException(__d('localized', '%s Not implemented yet.')); + $invalid_num = new InvalidNumberRule(); + + $invalid_num->add(null, 're[0-9]11', null, null); + $invalid_num->add(null, null, 're[0-9]11', null); + $invalid_num->add(null, 're[01][0-9][0-9]', null, null); + $invalid_num->add(null, null, 're[01][0-9][0-9]', null); + $invalid_num->add(null, null, 555, 'ra0100-0199'); + + // Unassigned area codes (incomplete) + $invalid_num->add(null, 'ra221-223', null, null); + $invalid_num->add(null, '230', null, null); + $invalid_num->add(null, 'ra232-233', null, null); + $invalid_num->add(null, '235', null, null); + $invalid_num->add(null, 'ra237-238', null, null); + $invalid_num->add(null, '241', null, null); + $invalid_num->add(null, 'ra243-245', null, null); + $invalid_num->add(null, '247', null, null); + $invalid_num->add(null, '255', null, null); + $invalid_num->add(null, 'ra257-259', null, null); + $invalid_num->add(null, '261', null, null); + $invalid_num->add(null, '263', null, null); + $invalid_num->add(null, 'ra265-266', null, null); + $invalid_num->add(null, '271', null, null); + $invalid_num->add(null, '273', null, null); + $invalid_num->add(null, '275', null, null); + $invalid_num->add(null, 'ra277-280', null, null); + $invalid_num->add(null, '282', null, null); + $invalid_num->add(null, 'ra285-288', null, null); + $invalid_num->add(null, 'ra290-300', null, null); + $invalid_num->add(null, 'ra370-379', null, null); + $invalid_num->add(null, '555', null, null); + $invalid_num->add(null, '595', null, null); + $invalid_num->add(null, '962', null, null); + + // Basic phone number pattern matching + $pattern = '/^(?:(?\+?1\s*(?:[.-]\s*)?)?'; + $pattern .= '(?\(\s*([0-9][0-9][0-9])\s*\)|([0-9][0-9][0-9]))\s*(?:[.-]\s*)?)'; + $pattern .= '(?[0-9][0-9][0-9])\s*(?:[.-]\s*)'; + $pattern .= '?(?[0-9]{4})'; + $pattern .= '(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/'; + + $passed_simple = (bool)preg_match($pattern, $check, $captured); + + $is_valid = false; + + if ($passed_simple) { + $is_valid = $invalid_num->isNumberValid($captured['country_code'], $captured['area_code'], $captured['coe_code'], $captured['subscriber_code']); + } + + return $is_valid; } /** @@ -59,3 +108,101 @@ public static function personId($check) throw new NotImplementedException(__d('localized', '%s Not implemented yet.')); } } + +class InvalidNumberRule +{ + private $number_rules = []; + + public function add($country_code=null, $area_code=null, $coe_code=null, $subscriber_code=null) { + $number_rule = [ + 'country_code' => $country_code, + 'area_code' => $area_code, + 'coe_code' => $coe_code, + 'subscriber_code' => $subscriber_code, + ]; + + array_push($this->number_rules, $number_rule); + } + + public function isNumberValid($country_code=null, $area_code=null, $coe_code=null, $subscriber_code=null) { + $phone_num_components = [ + 'country_code' => $country_code, + 'area_code' => $area_code, + 'coe_code' => $coe_code, + 'subscriber_code' => $subscriber_code + ]; + + $chars_to_remove = ['+', '-', '.', '(', ')']; + + foreach ($this->number_rules as $number_rule) { + $break = false; + $is_valid = [ + 'country_code' => true, + 'area_code' => true, + 'coe_code' => true, + 'subscriber_code' => true + ]; + + $false_counts = 0; + foreach ($number_rule as $number_rule_component) { + if ($number_rule_component != null) { + $false_counts++; + } + } + + foreach ($phone_num_components as $code_name => $code_value) { + $search_code = substr($number_rule[$code_name], 0, 2); + $code_value = str_replace($chars_to_remove, '', $code_value); + + // Check for a search code then remove it if it exists. + if ($search_code == 're' || $search_code == 'ra') { + $number_rule[$code_name] = substr($number_rule[$code_name], 2); + } + + if ($number_rule[$code_name] != null) { + // Search code is a regex. + if ($search_code == 're') { + + if ((bool)preg_match('/^'.$number_rule[$code_name].'$/', $code_value)) { + $is_valid[$code_name] = false; + $break = true; + } + // Search code is a range. + } else if ($search_code == 'ra') { + list($start, $end) = explode('-', $number_rule[$code_name]); + for ($i = $start; $i <= $end; $i+=1) { + if ($i == $code_value) { + $is_valid[$code_name] = false; + $break = true; + } + } + // No search code. Just a number. + } else { + if ($number_rule[$code_name] == $code_value) { + $is_valid[$code_name] = false; + $break = true; + } + } + } + + } + if ($break) { + break; + } + } + + $num_of_falses = 0; + foreach ($is_valid as $is_valid_component) { + if ($is_valid_component == false) { + $num_of_falses++; + } + } + + if ($num_of_falses == $false_counts) { + return false; + } else { + return true; + } + } +} + diff --git a/tests/TestCase/Validation/CaValidationTest.php b/tests/TestCase/Validation/CaValidationTest.php index a26ab25a..37a15c59 100644 --- a/tests/TestCase/Validation/CaValidationTest.php +++ b/tests/TestCase/Validation/CaValidationTest.php @@ -24,6 +24,63 @@ */ class CaValidationTest extends TestCase { + /** + * test the phone method of CaValidation + * + * @return void + */ + public function testPhone() + { + $this->assertTrue(CaValidation::phone('+1 702 425 5085')); + $this->assertFalse(CaValidation::phone('teststring')); + $this->assertFalse(CaValidation::phone('1-(33)-(333)-(4444)')); + $this->assertFalse(CaValidation::phone('1-(33)-3333-4444')); + $this->assertFalse(CaValidation::phone('1-(33)-33-4444')); + $this->assertFalse(CaValidation::phone('1-(33)-3-44444')); + $this->assertFalse(CaValidation::phone('1-(33)-3-444')); + $this->assertFalse(CaValidation::phone('1-(33)-3-44')); + + $this->assertFalse(CaValidation::phone('(055) 999-9999')); + $this->assertFalse(CaValidation::phone('(155) 999-9999')); + $this->assertFalse(CaValidation::phone('(595) 999-9999')); + $this->assertFalse(CaValidation::phone('(213) 099-9999')); + $this->assertFalse(CaValidation::phone('(213) 199-9999')); + + // invalid area-codes + $this->assertFalse(CaValidation::phone('1-(511)-999-9999')); + $this->assertFalse(CaValidation::phone('1-(379)-999-9999')); + $this->assertFalse(CaValidation::phone('1-(962)-999-9999')); + $this->assertFalse(CaValidation::phone('1-(295)-999-9999')); + $this->assertFalse(CaValidation::phone('1-(222)-248-9999')); + $this->assertFalse(CaValidation::phone('1 555 999-9999')); + + // invalid exhange + $this->assertFalse(CaValidation::phone('1-(705)-511-9999')); + + // fictitious phone numbers + $this->assertFalse(CaValidation::phone('1-(705)-555-0199')); + $this->assertFalse(CaValidation::phone('1-(705)-555-0122')); + + // valid phone numbers + $this->assertTrue(CaValidation::phone('1-(369)-333-4444')); + $this->assertTrue(CaValidation::phone('1-(973)-333-4444')); + $this->assertTrue(CaValidation::phone('1-(313)-555-9999')); + $this->assertTrue(CaValidation::phone('1-(705)-555-0299')); + + $this->assertTrue(CaValidation::phone('1 (705) 333 4444')); + $this->assertTrue(CaValidation::phone('+1 (705) 333 4444')); + $this->assertTrue(CaValidation::phone('(705) 333 4444')); + + $this->assertTrue(CaValidation::phone('1-(333)-333-4444')); + $this->assertTrue(CaValidation::phone('1.(333)-333-4444')); + $this->assertTrue(CaValidation::phone('1.(333).333-4444')); + $this->assertTrue(CaValidation::phone('1.(333).333.4444')); + $this->assertTrue(CaValidation::phone('1-333-333-4444')); + $this->assertFalse(CaValidation::phone('7002 425 5085')); + $this->assertTrue(CaValidation::phone('1 (705) 248 3242')); + $this->assertFalse(CaValidation::phone('1 %705# 248 3242')); + } + /** * test the postal method of CaValidation *