From 094130cf5b529b3dcae544a8e2c6651687bc7dab Mon Sep 17 00:00:00 2001 From: Jesse Aleksanter Kahtava Date: Wed, 25 Jan 2017 15:59:07 -0500 Subject: [PATCH 1/4] - phone numbers in Canada are of the same format as those in the USA. No need to throw NotImplemented. Copied the US phone validation rules to Canada. --- src/Validation/CaValidation.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Validation/CaValidation.php b/src/Validation/CaValidation.php index 853877bc..17aed9bc 100644 --- a/src/Validation/CaValidation.php +++ b/src/Validation/CaValidation.php @@ -45,7 +45,15 @@ public static function postal($check) */ public static function phone($check) { - throw new NotImplementedException(__d('localized', '%s Not implemented yet.')); + $pattern = '/^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|3[02-689][0-9]|9[02-57-9][0-9]|[246-8][02-46-8][02-46-9])\s*\)'; + $pattern .= '|(55[0-46-9]|5[0-46-9][5]|[0-46-9]55|[2-9]1[02-9]|[2-9][02-8]1|[2-46-9][02-46-8][02-46-9]))\s*(?:[.-]\s*)?)'; + $pattern .= '(?!(555(?:\s*(?:[.|\-|\s]\s*))(01([0-9][0-9])|1212)))'; + $pattern .= '(?!(555(01([0-9][0-9])|1212)))'; + $pattern .= '([2-9]1[02-9]|[2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)'; + $pattern .= '?([0-9]{4})'; + $pattern .= '(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/'; + + return (bool)preg_match($pattern, $check); } /** From 17da4d98e3dad96669fa3901f24524af581f15d1 Mon Sep 17 00:00:00 2001 From: Jesse Aleksanter Kahtava Date: Wed, 25 Jan 2017 16:13:40 -0500 Subject: [PATCH 2/4] - added phone number tests to CaValidationTest.php --- .../TestCase/Validation/CaValidationTest.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/TestCase/Validation/CaValidationTest.php b/tests/TestCase/Validation/CaValidationTest.php index a26ab25a..37a44e9a 100644 --- a/tests/TestCase/Validation/CaValidationTest.php +++ b/tests/TestCase/Validation/CaValidationTest.php @@ -24,6 +24,60 @@ */ 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-(555)-999-9999')); + + // invalid exhange + $this->assertFalse(CaValidation::phone('1-(222)-511-9999')); + + // invalid phone number + $this->assertFalse(CaValidation::phone('1-(222)-555-0199')); + $this->assertFalse(CaValidation::phone('1-(222)-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-(222)-555-0299')); + + $this->assertTrue(CaValidation::phone('1 (222) 333 4444')); + $this->assertTrue(CaValidation::phone('+1 (222) 333 4444')); + $this->assertTrue(CaValidation::phone('(222) 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')); + } + /** * test the postal method of CaValidation * From cb22f86bdab9474374751acc03717440c6a5f617 Mon Sep 17 00:00:00 2001 From: Jesse Aleksanter Kahtava Date: Thu, 26 Jan 2017 13:10:32 -0500 Subject: [PATCH 3/4] - made changes to CaValidation.php in the localized plugin.. It had a lot of problems and was difficult to maintain. --- src/Validation/CaValidation.php | 152 +++++++++++++++++- .../TestCase/Validation/CaValidationTest.php | 21 +-- 2 files changed, 157 insertions(+), 16 deletions(-) diff --git a/src/Validation/CaValidation.php b/src/Validation/CaValidation.php index 17aed9bc..48223752 100644 --- a/src/Validation/CaValidation.php +++ b/src/Validation/CaValidation.php @@ -45,15 +45,55 @@ public static function postal($check) */ public static function phone($check) { - $pattern = '/^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|3[02-689][0-9]|9[02-57-9][0-9]|[246-8][02-46-8][02-46-9])\s*\)'; - $pattern .= '|(55[0-46-9]|5[0-46-9][5]|[0-46-9]55|[2-9]1[02-9]|[2-9][02-8]1|[2-46-9][02-46-8][02-46-9]))\s*(?:[.-]\s*)?)'; - $pattern .= '(?!(555(?:\s*(?:[.|\-|\s]\s*))(01([0-9][0-9])|1212)))'; - $pattern .= '(?!(555(01([0-9][0-9])|1212)))'; - $pattern .= '([2-9]1[02-9]|[2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)'; - $pattern .= '?([0-9]{4})'; + $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 + $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+))?$/'; - return (bool)preg_match($pattern, $check); + $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; } /** @@ -67,3 +107,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 37a44e9a..37a15c59 100644 --- a/tests/TestCase/Validation/CaValidationTest.php +++ b/tests/TestCase/Validation/CaValidationTest.php @@ -51,24 +51,25 @@ public function testPhone() $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-(555)-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-(222)-511-9999')); + $this->assertFalse(CaValidation::phone('1-(705)-511-9999')); - // invalid phone number - $this->assertFalse(CaValidation::phone('1-(222)-555-0199')); - $this->assertFalse(CaValidation::phone('1-(222)-555-0122')); + // 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-(222)-555-0299')); + $this->assertTrue(CaValidation::phone('1-(705)-555-0299')); - $this->assertTrue(CaValidation::phone('1 (222) 333 4444')); - $this->assertTrue(CaValidation::phone('+1 (222) 333 4444')); - $this->assertTrue(CaValidation::phone('(222) 333 4444')); + $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')); @@ -76,6 +77,8 @@ public function testPhone() $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')); } /** From d3759901c88b6c63c8439dc4f1e1416d8c42430b Mon Sep 17 00:00:00 2001 From: Jesse Aleksanter Kahtava Date: Thu, 26 Jan 2017 13:16:03 -0500 Subject: [PATCH 4/4] - updated a comment --- src/Validation/CaValidation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Validation/CaValidation.php b/src/Validation/CaValidation.php index 48223752..e93a659b 100644 --- a/src/Validation/CaValidation.php +++ b/src/Validation/CaValidation.php @@ -46,13 +46,14 @@ public static function postal($check) public static function phone($check) { $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 + // 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);