diff --git a/Form/Type/PhoneNumberType.php b/Form/Type/PhoneNumberType.php
index 47184f70..00e9d0f6 100644
--- a/Form/Type/PhoneNumberType.php
+++ b/Form/Type/PhoneNumberType.php
@@ -55,7 +55,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
'compound' => false,
'default_region' => PhoneNumberUtil::UNKNOWN_REGION,
'format' => PhoneNumberFormat::INTERNATIONAL,
- 'invalid_message' => 'This is not a valid phone number.',
+ 'invalid_message' => 'This value is not a valid phone number.',
)
);
}
diff --git a/README.md b/README.md
index 74e6cd01..38379629 100644
--- a/README.md
+++ b/README.md
@@ -146,3 +146,10 @@ You can set the default region through the `defaultRegion` property:
* @AssertPhoneNumber(defaultRegion="GB")
*/
private $phoneNumber;
+
+By default any valid phone number will be accepted. You can restrict the type through the `type` property, recognised values are `mobile` and `fixed_line`. (Note the libphonenumber cannot always distinguish between mobile and fixed-line numbers (eg in the USA), in which case it will be accepted.)
+
+ /**
+ * @AssertPhoneNumber(type="mobile")
+ */
+ private $mobilePhoneNumber;
diff --git a/Resources/translations/validators.en.xlf b/Resources/translations/validators.en.xlf
new file mode 100644
index 00000000..6657896e
--- /dev/null
+++ b/Resources/translations/validators.en.xlf
@@ -0,0 +1,19 @@
+
+
+
+
+
+ This value is not a valid phone number.
+ This value is not a valid phone number.
+
+
+ This value is not a valid fixed-line number.
+ This value is not a valid fixed-line number.
+
+
+ This value is not a valid mobile number.
+ This value is not a valid mobile number.
+
+
+
+
diff --git a/Resources/translations/validators.en_CA.xlf b/Resources/translations/validators.en_CA.xlf
new file mode 100644
index 00000000..9f1e45ea
--- /dev/null
+++ b/Resources/translations/validators.en_CA.xlf
@@ -0,0 +1,11 @@
+
+
+
+
+
+ This value is not a valid mobile number.
+ This value is not a valid cell number.
+
+
+
+
diff --git a/Resources/translations/validators.en_PH.xlf b/Resources/translations/validators.en_PH.xlf
new file mode 100644
index 00000000..44f1f642
--- /dev/null
+++ b/Resources/translations/validators.en_PH.xlf
@@ -0,0 +1,11 @@
+
+
+
+
+
+ This value is not a valid mobile number.
+ This value is not a valid handphone number.
+
+
+
+
diff --git a/Resources/translations/validators.en_SG.xlf b/Resources/translations/validators.en_SG.xlf
new file mode 100644
index 00000000..44f1f642
--- /dev/null
+++ b/Resources/translations/validators.en_SG.xlf
@@ -0,0 +1,11 @@
+
+
+
+
+
+ This value is not a valid mobile number.
+ This value is not a valid handphone number.
+
+
+
+
diff --git a/Resources/translations/validators.en_US.xlf b/Resources/translations/validators.en_US.xlf
new file mode 100644
index 00000000..9f1e45ea
--- /dev/null
+++ b/Resources/translations/validators.en_US.xlf
@@ -0,0 +1,11 @@
+
+
+
+
+
+ This value is not a valid mobile number.
+ This value is not a valid cell number.
+
+
+
+
diff --git a/Resources/translations/validators.en_ZA.xlf b/Resources/translations/validators.en_ZA.xlf
new file mode 100644
index 00000000..9f1e45ea
--- /dev/null
+++ b/Resources/translations/validators.en_ZA.xlf
@@ -0,0 +1,11 @@
+
+
+
+
+
+ This value is not a valid mobile number.
+ This value is not a valid cell number.
+
+
+
+
diff --git a/Tests/Validator/Constraints/PhoneNumberTest.php b/Tests/Validator/Constraints/PhoneNumberTest.php
index abeb8795..cc4ee3b0 100644
--- a/Tests/Validator/Constraints/PhoneNumberTest.php
+++ b/Tests/Validator/Constraints/PhoneNumberTest.php
@@ -29,4 +29,38 @@ public function testProperties()
$this->assertObjectHasAttribute('type', $phoneNumber);
$this->assertObjectHasAttribute('defaultRegion', $phoneNumber);
}
+
+ /**
+ * @dataProvider messageProvider
+ */
+ public function testMessage($message = null, $type = null, $expectedMessage)
+ {
+ $phoneNumber = new PhoneNumber();
+
+ if (null !== $message) {
+ $phoneNumber->message = $message;
+ }
+ if (null !== $type) {
+ $phoneNumber->type = $type;
+ }
+
+ $this->assertSame($expectedMessage, $phoneNumber->getMessage());
+ }
+
+ /**
+ * 0 => Message (optional)
+ * 1 => Type (optional)
+ * 2 => Expected message
+ */
+ public function messageProvider()
+ {
+ return array(
+ array(null, null, 'This value is not a valid phone number.'),
+ array(null, 'fixed_line', 'This value is not a valid fixed-line number.'),
+ array(null, 'mobile', 'This value is not a valid mobile number.'),
+ array('foo', null, 'foo'),
+ array('foo', 'fixed_line', 'foo'),
+ array('foo', 'mobile', 'foo'),
+ );
+ }
}
diff --git a/Tests/Validator/Constraints/PhoneNumberValidatorTest.php b/Tests/Validator/Constraints/PhoneNumberValidatorTest.php
index e9d93b9c..37737cdb 100644
--- a/Tests/Validator/Constraints/PhoneNumberValidatorTest.php
+++ b/Tests/Validator/Constraints/PhoneNumberValidatorTest.php
@@ -11,6 +11,8 @@
namespace Misd\PhoneNumberBundle\Tests\Validator\Constraints;
+use libphonenumber\PhoneNumber as PhoneNumberObject;
+use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use Misd\PhoneNumberBundle\Validator\Constraints\PhoneNumber;
use Misd\PhoneNumberBundle\Validator\Constraints\PhoneNumberValidator;
@@ -33,17 +35,32 @@ public function testInstanceOf()
/**
* @dataProvider validateProvider
*/
- public function testValidate($value, $violates, $defaultRegion = PhoneNumberUtil::UNKNOWN_REGION)
+ public function testValidate($value, $violates, $type = null, $defaultRegion = null)
{
$validator = new PhoneNumberValidator();
$context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface');
$validator->initialize($context);
$constraint = new PhoneNumber();
- $constraint->defaultRegion = $defaultRegion;
+ if (null !== $type) {
+ $constraint->type = $type;
+ }
+ if (null !== $defaultRegion) {
+ $constraint->defaultRegion = $defaultRegion;
+ }
if (true === $violates) {
- $context->expects($this->once())->method('addViolation');
+ if ($value instanceof PhoneNumberObject) {
+ $constraintValue = PhoneNumberUtil::getInstance()->format($value, PhoneNumberFormat::INTERNATIONAL);
+ } else {
+ $constraintValue = (string) $value;
+ }
+
+ $context->expects($this->once())->method('addViolation')
+ ->with(
+ $constraint->getMessage(),
+ array('{{ type }}' => $constraint->type, '{{ value }}' => $constraintValue)
+ );
} else {
$context->expects($this->never())->method('addViolation');
}
@@ -54,7 +71,8 @@ public function testValidate($value, $violates, $defaultRegion = PhoneNumberUtil
/**
* 0 => Value
* 1 => Violates?
- * 2 => Default region (optional)
+ * 2 => Type (optional)
+ * 3 => Default region (optional)
*/
public function validateProvider()
{
@@ -62,9 +80,21 @@ public function validateProvider()
array(null, false),
array('', false),
array(PhoneNumberUtil::getInstance()->parse('+441234567890', PhoneNumberUtil::UNKNOWN_REGION), false),
+ array(PhoneNumberUtil::getInstance()->parse('+441234567890', PhoneNumberUtil::UNKNOWN_REGION), false, 'fixed_line'),
+ array(PhoneNumberUtil::getInstance()->parse('+441234567890', PhoneNumberUtil::UNKNOWN_REGION), true, 'mobile'),
array(PhoneNumberUtil::getInstance()->parse('+44123456789', PhoneNumberUtil::UNKNOWN_REGION), true),
array('+441234567890', false),
- array('01234 567890', false, 'GB'),
+ array('+441234567890', false, 'fixed_line'),
+ array('+441234567890', true, 'mobile'),
+ array('+44123456789', true),
+ array('+44123456789', true, 'mobile'),
+ array('+12015555555', false),
+ array('+12015555555', false, 'fixed_line'),
+ array('+12015555555', false, 'mobile'),
+ array('2015555555', false, null, 'US'),
+ array('2015555555', false, 'fixed_line', 'US'),
+ array('2015555555', false, 'mobile', 'US'),
+ array('01234 567890', false, null, 'GB'),
array('foo', true),
);
}
diff --git a/Validator/Constraints/PhoneNumber.php b/Validator/Constraints/PhoneNumber.php
index 2af9cfac..68260eab 100644
--- a/Validator/Constraints/PhoneNumber.php
+++ b/Validator/Constraints/PhoneNumber.php
@@ -23,7 +23,42 @@
*/
class PhoneNumber extends Constraint
{
- public $message = 'This value is not a valid {{ type }} number.';
- public $type = 'phone';
+ const ANY = 'any';
+ const FIXED_LINE = 'fixed_line';
+ const MOBILE = 'mobile';
+
+ private $anyMessage = 'This value is not a valid phone number.';
+ private $fixedLineMessage = 'This value is not a valid fixed-line number.';
+ private $mobileMessage = 'This value is not a valid mobile number.';
+
+ public $message = null;
+ public $type = self::ANY;
public $defaultRegion = PhoneNumberUtil::UNKNOWN_REGION;
+
+ public function getType()
+ {
+ switch ($this->type) {
+ case self::FIXED_LINE:
+ case self::MOBILE:
+ return $this->type;
+ }
+
+ return self::ANY;
+ }
+
+ public function getMessage()
+ {
+ if (null !== $this->message) {
+ return $this->message;
+ }
+
+ switch ($this->type) {
+ case self::FIXED_LINE:
+ return $this->fixedLineMessage;
+ case self::MOBILE:
+ return $this->mobileMessage;
+ }
+
+ return $this->anyMessage;
+ }
}
diff --git a/Validator/Constraints/PhoneNumberValidator.php b/Validator/Constraints/PhoneNumberValidator.php
index 74665601..2bcce9f2 100644
--- a/Validator/Constraints/PhoneNumberValidator.php
+++ b/Validator/Constraints/PhoneNumberValidator.php
@@ -14,6 +14,7 @@
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumber as PhoneNumberObject;
use libphonenumber\PhoneNumberFormat;
+use libphonenumber\PhoneNumberType;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
@@ -61,6 +62,29 @@ public function validate($value, Constraint $constraint)
return;
}
+
+ switch ($constraint->getType()) {
+ case PhoneNumber::FIXED_LINE:
+ $validTypes = array(PhoneNumberType::FIXED_LINE, PhoneNumberType::FIXED_LINE_OR_MOBILE);
+ break;
+ case PhoneNumber::MOBILE:
+ $validTypes = array(PhoneNumberType::MOBILE, PhoneNumberType::FIXED_LINE_OR_MOBILE);
+ break;
+ default:
+ $validTypes = array();
+ break;
+ }
+
+ if (count($validTypes)) {
+ $type = $phoneUtil->getNumberType($phoneNumber);
+
+ if (false === in_array($type, $validTypes)) {
+ $this->addViolation($value, $constraint);
+
+ return;
+ }
+
+ }
}
/**
@@ -72,8 +96,8 @@ public function validate($value, Constraint $constraint)
private function addViolation($value, Constraint $constraint)
{
$this->context->addViolation(
- $constraint->message,
- array('{{ type }}' => $constraint->type, '{{ value }}' => $value)
+ $constraint->getMessage(),
+ array('{{ type }}' => $constraint->getType(), '{{ value }}' => $value)
);
}
}