2011-09-22 16 views
21

Tôi muốn áp dụng các trình xác nhận hợp lệ trên một thuộc tính đối tượng chỉ khi giá trị không rỗng.Làm thế nào để cho phép các giá trị rỗng trong các trình xác thực của symfony2

Bây giờ tiêu chuẩn symfony hành vi:

class Entity 
{ 
    /** 
    * @ORM\Column(type="string", nullable=true) 
    * @Assert\Email() 
    */ 
    protected $email; 
    (...) 
} 

rằng đối tượng sẽ không vượt qua xác nhận nếu một email là null, hoặc chuỗi rỗng, là có cách nào để nói validator để khẳng định như một giá trị, một giá trị rỗng, và xác nhận chỉ khi trường có dữ liệu?

PS Tôi biết rằng tôi có thể viết trình xác thực gọi lại, nhưng việc ghi lại gọi lại cho mọi trường chỉ để có tính năng "allowEmpty" không đẹp như vậy.

Trả lời

22

Bạn phải đặt rõ ràng 'required' => false trong lớp FormBuilder của mình cho tất cả các trường tùy chọn. Đây là một đoạn mô tả field type options.


Chỉnh sửa. Nhận được một vài downvotes. Theo mặc định tất cả trình xác thực sẽ xử lý các giá trị null hợp lệ, ngoại trừNotNullNotEmpty. Cả hai đều không được sử dụng trong câu hỏi. Câu hỏi là ngầm về cách tắt thuộc tính required phía máy khách được bật theo mặc định.

+26

Đây không phải là câu trả lời đúng. tùy chọn 'bắt buộc' chỉ thực thi xác thực phía máy khách. – TyrionLannister

+7

@TyrionLannister Bạn thực sự là chính xác. Tuy nhiên, không có trình xác nhận hợp lệ mặc định nào dẫn đến một giá trị rỗng được xử lý không hợp lệ trừ khi có các ràng buộc 'NotNull()' và 'NotEmpty()'. Thấy như người hỏi không có những ràng buộc đó, nó ngầm định rằng vấn đề là với thuộc tính HTML5 'required' phía máy khách. – gilden

+3

@gilden với tất cả sự tôn trọng, thuộc tính 'required' không có gì phổ biến với giá trị trống được phê duyệt. Nó chỉ được sử dụng bởi xác nhận hợp lệ phía máy khách HTML5 và nó không liên quan đến việc xác nhận hợp lệ (phía máy chủ). –

19

Đặt tùy chọn này required không phải là giải pháp:

Cũng lưu ý rằng thiết lập các tùy chọn cần thiết để thực sự sẽ không dẫn đến xác nhận server-side được áp dụng. Nói cách khác, nếu người dùng gửi một giá trị trống cho trường (ví dụ như với trình duyệt cũ hoặc dịch vụ web), nó sẽ được chấp nhận như một giá trị hợp lệ trừ khi bạn sử dụng ràng buộc xác thực NotBlank hoặc NotNull của Symfony.

http://symfony.com/doc/current/book/forms.html#field-type-options

Đối với xác nhận tùy chỉnh của tôi, tôi thêm một

if (null == $value) { 
    return true; 
} 

với phương pháp isValid(). Tuy nhiên, tôi không chắc chắn những gì sẽ là cách tốt nhất cho các lớp validator tiêu chuẩn.

+1

câu trả lời này là câu trả lời được chấp nhận, bởi vì câu trả lời được chấp nhận chỉ áp dụng cho các trường đơn giản không dành cho trường nhập được nhúng –

1

Đây là lừa tôi thấy thực sự:

https://github.com/symfony/symfony/issues/5906

Bạn cần phải viết một biến dữ liệu mà không làm gì, và sau đó thêm nó vào lĩnh vực của bạn. Sau đó, juste gọi phương thức submit() với tham số thứ hai là false.

Lưu ý rằng nó ổn với Symfony 2.3.

2

Chỉ trong trường hợp bất kỳ ai khác gặp phải cùng một câu hỏi này. Tôi thích cá nhân giải quyết nó bằng cách thêm thuộc tính sau vào mẫu Twig của tôi:

{{ form_row(form.<field>, {'required': false}) }} 
+1

Tôi không nghĩ bạn muốn mã hóa mã này trong mẫu của mình. Nếu bạn muốn sử dụng phương pháp 'require', hãy sử dụng gợi ý của gilden và thêm nó vào trình tạo biểu mẫu. – Luke

+0

Vâng trong hầu hết trường hợp, tôi nghĩ đó sẽ là một cách tiếp cận tốt hơn (như vậy các yêu cầu xác thực thuộc tính truyền bá qua các mẫu khác), tuy nhiên trong một số trường hợp (ví dụ như các ứng dụng đơn giản) đặt nó vào một mẫu Twig không quá khủng khiếp :) –

0

Loại trường Đoán tìm cách xử lý này. http://symfony.com/doc/current/book/forms.html#field-type-guessing

Nó phụ thuộc vào mẫu tờ khai của bạn: "Các 'đoán' được kích hoạt khi bạn bỏ qua đối số thứ hai cho phương thức add() (hoặc nếu bạn vượt qua null để nó) Nếu bạn vượt qua một mảng tùy chọn. làm đối số thứ ba (được thực hiện cho ngày đến hạn), các tùy chọn này được áp dụng cho trường được đoán. "

2

nếu tôi hiểu chính xác bạn chỉ muốn xác thực phía máy chủ nếu giá trị được nhập. Tôi chính xác trong cùng một kịch bản. Tôi muốn xác thực URL chỉ khi URL được cung cấp. Cách tốt nhất tôi bắt gặp là viết lớp xác nhận tùy chỉnh của riêng tôi. Bạn có thể viết một lớp xác nhận tùy chỉnh chung chung.

Tôi đã nhấp vào liên kết này https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html ngoại trừ một số thay đổi do phiên bản mới nhất của symfony. Đây là việc thực hiện

Acme \ BundleNameBundle \ Validator \ chế \ cstmUrl

namespace Acme\BundleNameBundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\Constraints\Url; 

/** 
* @Annotation 
*/ 
class CstmUrl extends Url 
{ 
    public $message = 'The URL "%string%" is not valid'; 
} 

Acme \ BundleNameBundle \ Validator \ chế \ cstmUrlValidator

namespace Acme\BundleNameBundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\Constraints\Url; 
use Symfony\Component\Validator\Constraints\UrlValidator; 

class CstmUrlValidator extends UrlValidator 
{ 
    public function validate($value, Constraint $constraint) 
    { 
     if(!$value || empty($value)) 
      return true; 

     parent::validate($value, $constraint); 
    } 
} 

Validtion.yml

Acme\BundleNameBundle\Entity\Student: 
    Url: 
     - Acme\BundleNameBundle\Validator\Constraints\CstmUrl: ~ 

bên trong điều khiển chỉ ràng buộc hạn chế bạn vẫn thường làm

'constraints'=> new CstmUrl(array("message"=>"Invalid url provided")) 

tôi chắc chắn có thể có những cách khác tốt hơn để làm việc đó, nhưng bây giờ tôi cảm thấy điều này không được công việc tốt.

Các vấn đề liên quan