2012-09-21 11 views
7

सभी मुझे क्या करने की कोशिश कर रहा हूँ:Symonfy2 सत्यापन: YML में बाधाओं को परिभाषित है, और एक सरणी को मान्य

  1. एक सरणी

मान्य करने के लिए YML में बाधाओं को परिभाषित

  • इस प्रयोग

    कहें, एक उत्पाद सरणी:

    $product['name'] = 'A book'; 
    $product['date'] = '2012-09'; 
    $product['price'] = '21.5'; 
    

    यह कैसे करें?

  • उत्तर

    -1
    अपने validation.yml में

    :

    Acme\DemoBundle\Entity\AcmeEntity: 
        properties: 
         price: 
          - NotBlank: ~ 
          - Acme\DemoBundle\Validator\Constraints\ContainsAlphanumeric: ~ 
    

    और अपने ContainsAlphanumeric:

    <?php 
        namespace Acme\DemoBundle\Validator\Constraints; 
        use Symfony\Component\Validator\Constraint; 
        use Symfony\Component\Validator\ConstraintValidator; 
    
        class ContainsAlphanumericValidator extends ConstraintValidator 
        { 
         public function validate($value, Constraint $constraint) 
         { 
          if (!preg_match('/^[a-zA-Za0-9]+$/', $value, $matches)) { 
           $this->context->addViolation($constraint->message, array('%string%' => $value)); 
          } 
         } 
        } 
    ?> 
    
    +1

    यह किसी इकाई ऑब्जेक्ट को सत्यापित करने के लिए है, जो मैं चाहता हूं –

    1

    तरह से एक सरणी को मान्य करने के लिए आसान है, मैं यह silex documentation

    use Symfony\Component\Validator\Constraints as Assert; 
    
    ... 
    ... 
    
    $constraint = new Assert\Collection(array(
        'Name' => new Assert\MinLength(10), 
        'author' => new Assert\Collection(array(
         'first_name' => array(new Assert\NotBlank(), new Assert\MinLength(10)), 
         'last_name' => new Assert\MinLength(10), 
        )), 
    )); 
    $errors = $this->get('validator')->validateValue($book, $constraint); 
    
    में सीखा है है

    या आप बाधाओं के साथ सीधे रूप बना सकते हैं

    $form = $this->get('form.factory')->createBuilder('form',array(),array(
        'csrf_protection'  => false, 
        'validation_constraint' => new Assert\Collection(array(
         'name'  => new Assert\NotBlank(array(
          'message' => 'Can\'t be null' 
         )), 
         'email'  => new Assert\Email(array(
          'message' => 'Invalid email' 
         )), 
        )) 
    )) 
    ->add('name', 'text') 
    ->add('email', 'email') 
    ->getForm(); 
    
    } 
    

    इस कोड को अपनी दूसरी बात हल कर सकते हैं, लेकिन पहले बिंदु मैं सुझाव है कि आप कि वस्तुओं instantiated सत्यापन बाधा के साथ एक मान्य बाधाओं सरणी के लिए अपने YAML परिभाषा बदल देती है एक कस्टम वर्ग लिख सकते हैं या हो सकता है कि सीधे एक रूप देता है करने के लिए!

    मुझे symfony2 में ऐसा करने के लिए तैयार कक्षा के बारे में पता नहीं है।

    मैंने इसे अन्य परियोजनाओं में किया है जिनके पास एक अच्छा डेटा मॉडल नहीं है, लेकिन सिम्फनी में आप अपने मॉडल बना सकते हैं और इसके साथ जुड़े सत्यापन को परिभाषित कर सकते हैं।

    +0

    धन्यवाद लेकिन क्या यह yml में बाधाओं को परिभाषित करना संभव है? –

    +0

    जैसा कि आप देख सकते हैं कि बाधाएं ऑब्जेक्ट्स की एक साधारण सरणी हैं, आप इस सरणी को yaml फ़ाइल में परिभाषित कर सकते हैं, फिर yaml फ़ाइल को सरणी में लोड कर सकते हैं और ऑब्जेक्ट को उनके नाम से तुरंत चालू कर सकते हैं। मुझे खेद है, लेकिन आपको इसे कस्टम क्लास/विधि के साथ करने की ज़रूरत है जिसे आपको बनाने की ज़रूरत है, मैंने आपको बताया कि यह कैसे होना चाहिए :) –

    4

    सबसे पहले, आपको यह जानना होगा कि सिम्फनी 2 वैधकर्ता आसानी से ऐसा करने के लिए तैयार नहीं हैं। मुझे कुछ समय और कुछ सिम्फनी 2 स्रोत पढ़ने के लिए आपके मामले के लिए एक समाधान समाधान प्राप्त हुआ, और मेरा समाधान प्राकृतिक नहीं है।

    मैंने एक कक्षा बनाई है जो वैधकर्ता, आपकी सरणी और आपकी यम कॉन्फ़िगरेशन फ़ाइल लेती है ताकि आप जो भी उम्मीद कर सकें वह कर सकें। यह वर्ग YamlFileLoader को सिम्फनी से सुरक्षित parseNodes विधि तक पहुंचने के लिए विस्तारित करता है: यह सुंदर नहीं है, लेकिन यह एकमात्र तरीका है जिसे मैंने कस्टम Yaml कॉन्फ़िगरेशन फ़ाइल को Constraint ऑब्जेक्ट की सरणी में बदलने के लिए पाया है।

    तो हम यहां हैं। मैं आपको अपना कोड देता हूं, आपको अपने नाम के अनुसार कुछ नामस्थानों को प्रतिस्थापित करने की आवश्यकता होगी।

    पहले, हमारे डेमो के लिए एक नियंत्रक बनाने के लिए:

    public function indexAction() 
        { 
    
         // We create a sample validation file for the demo 
         $demo = <<< EOT 
    name: 
        - NotBlank: ~ 
        - MinLength: { limit: 3 } 
        - MaxLength: { limit: 10 } 
    date: 
        - NotBlank: ~ 
        - Regex: "/^[0-9]{4}\-[0-9]{2}$/" 
    price: 
        - Min: 0 
    
    EOT; 
         file_put_contents("/tmp/test.yml", $demo); 
    
         // We create your array to validate 
         $product = array(); 
         $product['name'] = 'A book'; 
         $product['date'] = '2012-09'; 
         $product['price'] = '21.5'; 
    
         $validator = $this->get('validator'); 
         $service = new \Fuz\TestsBundle\Services\ArrayValidator($validator, $product, "/tmp/test.yml"); 
         $errors = $service->validate(); 
    
         echo '<pre>'; 
         var_dump($errors); 
         die(); 
    
         return $this->render('FuzTestsBundle:Default:index.html.twig'); 
        } 
    

    फिर एक वर्ग ArrayValidator.php नामित पैदा करते हैं। फिर, नामस्थान का ख्याल रखना।

    <?php 
    
    namespace Fuz\TestsBundle\Services; 
    
    use Symfony\Component\Validator\ValidatorInterface; 
    use Symfony\Component\Yaml\Parser; 
    use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader; 
    
    /** 
    * This class inherits from YamlFileLoader because we need to call the 
    * parseNodes() protected method. 
    */ 
    class ArrayValidator extends YamlFileLoader 
    { 
    
        /* the @validator service */ 
        private $validator; 
    
        /* The array to check */ 
        private $array; 
    
        /* The file that contains your validation rules */ 
        private $validationFile; 
    
        public function __construct(ValidatorInterface $validator, array $array = array(), $validationFile) 
        { 
         $this->validator = $validator; 
         $this->array = $array; 
         $this->validationFile = $validationFile; 
        } 
    
        /* The method that does what you want */ 
        public function validate() 
        { 
         $yaml = file_get_contents($this->validationFile); 
    
         // We parse the yaml validation file 
         $parser = new Parser(); 
         $parsedYaml = $parser->parse($yaml); 
    
         // We transform this validation array to a Constraint array 
         $arrayConstraints = $this->parseNodes($parsedYaml); 
    
         // For each elements of the array, we execute the validation 
         $errors = array(); 
         foreach ($this->array as $key => $value) 
         { 
          $errors[$key] = array(); 
    
          // If the array key (eg: price) has validation rules, we check the value 
          if (isset($arrayConstraints[$key])) 
          { 
           foreach ($arrayConstraints[$key] as $constraint) 
           { 
            // If there is constraint violations, we list messages 
            $violationList = $this->validator->validateValue($value, $constraint); 
            if (count($violationList) > 0) 
            { 
             foreach ($violationList as $violation) 
             { 
              $errors[$key][] = $violation->getMessage(); 
             } 
            } 
           } 
          } 
         } 
    
         return $errors; 
        } 
    
    } 
    

    अंत में, इसे अपने $ उत्पाद सरणी में विभिन्न मानों के साथ परीक्षण करें।

    डिफ़ॉल्ट रूप से:

     $product = array(); 
         $product['name'] = 'A book'; 
         $product['date'] = '2012-09'; 
         $product['price'] = '21.5'; 
    

    विल प्रदर्शन:

    array(3) { 
        ["name"]=> 
        array(0) { 
        } 
        ["date"]=> 
        array(0) { 
        } 
        ["price"]=> 
        array(0) { 
        } 
    } 
    

    हम करने के लिए मूल्यों को बदलते हैं:

    $product = array(); 
        $product['name'] = 'A very interesting book'; 
        $product['date'] = '2012-09-03'; 
        $product['price'] = '-21.5'; 
    

    आप मिल जाएगा:

    array(3) { 
        ["name"]=> 
        array(1) { 
        [0]=> 
        string(61) "This value is too long. It should have 10 characters or less." 
        } 
        ["date"]=> 
        array(1) { 
        [0]=> 
        string(24) "This value is not valid." 
        } 
        ["price"]=> 
        array(1) { 
        [0]=> 
        string(31) "This value should be 0 or more." 
        } 
    } 
    

    उम्मीद है कि यह मदद करता है।

    +0

    धन्यवाद, यह एक अच्छा जवाब/स्पष्टीकरण है। भगवान आपका भला करे;) – lexeme

    संबंधित मुद्दे