vendor/symfony/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\DomCrawler\Field;
       
    13 
       
    14 /**
       
    15  * ChoiceFormField represents a choice form field.
       
    16  *
       
    17  * It is constructed from a HTML select tag, or a HTML checkbox, or radio inputs.
       
    18  *
       
    19  * @author Fabien Potencier <fabien@symfony.com>
       
    20  *
       
    21  * @api
       
    22  */
       
    23 class ChoiceFormField extends FormField
       
    24 {
       
    25     private $type;
       
    26     private $multiple;
       
    27     private $options;
       
    28 
       
    29     /**
       
    30      * Returns true if the field should be included in the submitted values.
       
    31      *
       
    32      * @return Boolean true if the field should be included in the submitted values, false otherwise
       
    33      */
       
    34     public function hasValue()
       
    35     {
       
    36         // don't send a value for unchecked checkboxes
       
    37         if (in_array($this->type, array('checkbox', 'radio')) && null === $this->value) {
       
    38             return false;
       
    39         }
       
    40 
       
    41         return true;
       
    42     }
       
    43 
       
    44     /**
       
    45      * Sets the value of the field.
       
    46      *
       
    47      * @param string $value The value of the field
       
    48      *
       
    49      * @throws \InvalidArgumentException When value type provided is not correct
       
    50      *
       
    51      * @api
       
    52      */
       
    53     public function select($value)
       
    54     {
       
    55         $this->setValue($value);
       
    56     }
       
    57 
       
    58     /**
       
    59      * Ticks a checkbox.
       
    60      *
       
    61      * @throws \InvalidArgumentException When value type provided is not correct
       
    62      *
       
    63      * @api
       
    64      */
       
    65     public function tick()
       
    66     {
       
    67         if ('checkbox' !== $this->type) {
       
    68             throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type));
       
    69         }
       
    70 
       
    71         $this->setValue(true);
       
    72     }
       
    73 
       
    74     /**
       
    75      * Ticks a checkbox.
       
    76      *
       
    77      * @throws \InvalidArgumentException When value type provided is not correct
       
    78      *
       
    79      * @api
       
    80      */
       
    81     public function untick()
       
    82     {
       
    83         if ('checkbox' !== $this->type) {
       
    84             throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type));
       
    85         }
       
    86 
       
    87         $this->setValue(false);
       
    88     }
       
    89 
       
    90     /**
       
    91      * Sets the value of the field.
       
    92      *
       
    93      * @param string $value The value of the field
       
    94      *
       
    95      * @throws \InvalidArgumentException When value type provided is not correct
       
    96      */
       
    97     public function setValue($value)
       
    98     {
       
    99         if ('checkbox' == $this->type && false === $value) {
       
   100             // uncheck
       
   101             $this->value = null;
       
   102         } elseif ('checkbox' == $this->type && true === $value) {
       
   103             // check
       
   104             $this->value = $this->options[0];
       
   105         } else {
       
   106             if (is_array($value)) {
       
   107                 if (!$this->multiple) {
       
   108                     throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name));
       
   109                 }
       
   110 
       
   111                 foreach ($value as $v) {
       
   112                     if (!in_array($v, $this->options)) {
       
   113                         throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->options)));
       
   114                     }
       
   115                 }
       
   116             } elseif (!in_array($value, $this->options)) {
       
   117                 throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->options)));
       
   118             }
       
   119 
       
   120             if ($this->multiple) {
       
   121                 $value = (array) $value;
       
   122             }
       
   123 
       
   124             if (is_array($value)) {
       
   125                 $this->value = $value;
       
   126             } else {
       
   127                 parent::setValue($value);
       
   128             }
       
   129         }
       
   130     }
       
   131 
       
   132     /**
       
   133      * Adds a choice to the current ones.
       
   134      *
       
   135      * This method should only be used internally.
       
   136      *
       
   137      * @param \DOMNode $node A \DOMNode
       
   138      *
       
   139      * @throws \LogicException When choice provided is not multiple nor radio
       
   140      */
       
   141     public function addChoice(\DOMNode $node)
       
   142     {
       
   143         if (!$this->multiple && 'radio' != $this->type) {
       
   144             throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name));
       
   145         }
       
   146 
       
   147         $this->options[] = $value = $node->hasAttribute('value') ? $node->getAttribute('value') : '1';
       
   148 
       
   149         if ($node->getAttribute('checked')) {
       
   150             $this->value = $value;
       
   151         }
       
   152     }
       
   153 
       
   154     /**
       
   155      * Returns the type of the choice field (radio, select, or checkbox).
       
   156      *
       
   157      * @return string The type
       
   158      */
       
   159     public function getType()
       
   160     {
       
   161         return $this->type;
       
   162     }
       
   163 
       
   164     /**
       
   165      * Returns true if the field accepts multiple values.
       
   166      *
       
   167      * @return Boolean true if the field accepts multiple values, false otherwise
       
   168      */
       
   169     public function isMultiple()
       
   170     {
       
   171         return $this->multiple;
       
   172     }
       
   173 
       
   174     /**
       
   175      * Initializes the form field.
       
   176      *
       
   177      * @throws \LogicException When node type is incorrect
       
   178      */
       
   179     protected function initialize()
       
   180     {
       
   181         if ('input' != $this->node->nodeName && 'select' != $this->node->nodeName) {
       
   182             throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName));
       
   183         }
       
   184 
       
   185         if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) {
       
   186             throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type')));
       
   187         }
       
   188 
       
   189         $this->value = null;
       
   190         $this->options = array();
       
   191         $this->multiple = false;
       
   192 
       
   193         if ('input' == $this->node->nodeName) {
       
   194             $this->type = $this->node->getAttribute('type');
       
   195             $this->options[] = $value = $this->node->hasAttribute('value') ? $this->node->getAttribute('value') : '1';
       
   196 
       
   197             if ($this->node->getAttribute('checked')) {
       
   198                 $this->value = $value;
       
   199             }
       
   200         } else {
       
   201             $this->type = 'select';
       
   202             if ($this->node->hasAttribute('multiple')) {
       
   203                 $this->multiple = true;
       
   204                 $this->value = array();
       
   205                 $this->name = str_replace('[]', '', $this->name);
       
   206             }
       
   207 
       
   208             $found = false;
       
   209             foreach ($this->xpath->query('descendant::option', $this->node) as $option) {
       
   210                 $this->options[] = $option->getAttribute('value');
       
   211 
       
   212                 if ($option->getAttribute('selected')) {
       
   213                     $found = true;
       
   214                     if ($this->multiple) {
       
   215                         $this->value[] = $option->getAttribute('value');
       
   216                     } else {
       
   217                         $this->value = $option->getAttribute('value');
       
   218                     }
       
   219                 }
       
   220             }
       
   221 
       
   222             // if no option is selected and if it is a simple select box, take the first option as the value
       
   223             $option = $this->xpath->query('descendant::option', $this->node)->item(0);
       
   224             if (!$found && !$this->multiple && $option instanceof \DOMElement) {
       
   225                 $this->value = $option->getAttribute('value');
       
   226             }
       
   227         }
       
   228     }
       
   229 }