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 12namespace Symfony\Component\Form\Extension\Core\DataTransformer; 13 14use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface; 15use Symfony\Component\Form\DataTransformerInterface; 16use Symfony\Component\Form\Exception\TransformationFailedException; 17 18/** 19 * @author Bernhard Schussek <bschussek@gmail.com> 20 */ 21class ChoicesToBooleanArrayTransformer implements DataTransformerInterface 22{ 23 private $choiceList; 24 25 public function __construct(ChoiceListInterface $choiceList) 26 { 27 $this->choiceList = $choiceList; 28 } 29 30 /** 31 * Transforms an array of choices to a format appropriate for the nested 32 * checkboxes/radio buttons. 33 * 34 * The result is an array with the options as keys and true/false as values, 35 * depending on whether a given option is selected. If this field is rendered 36 * as select tag, the value is not modified. 37 * 38 * @param mixed $array An array 39 * 40 * @return mixed An array 41 * 42 * @throws TransformationFailedException If the given value is not an array 43 * or if the choices can not be retrieved. 44 */ 45 public function transform($array) 46 { 47 if (null === $array) { 48 return array(); 49 } 50 51 if (!is_array($array)) { 52 throw new TransformationFailedException('Expected an array.'); 53 } 54 55 try { 56 $values = $this->choiceList->getValues(); 57 } catch (\Exception $e) { 58 throw new TransformationFailedException('Can not get the choice list', $e->getCode(), $e); 59 } 60 61 $valueMap = array_flip($this->choiceList->getValuesForChoices($array)); 62 63 foreach ($values as $i => $value) { 64 $values[$i] = isset($valueMap[$value]); 65 } 66 67 return $values; 68 } 69 70 /** 71 * Transforms a checkbox/radio button array to an array of choices. 72 * 73 * The input value is an array with the choices as keys and true/false as 74 * values, depending on whether a given choice is selected. The output 75 * is an array with the selected choices. 76 * 77 * @param mixed $values An array 78 * 79 * @return mixed An array 80 * 81 * @throws TransformationFailedException If the given value is not an array, 82 * if the recuperation of the choices 83 * fails or if some choice can't be 84 * found. 85 */ 86 public function reverseTransform($values) 87 { 88 if (!is_array($values)) { 89 throw new TransformationFailedException('Expected an array.'); 90 } 91 92 try { 93 $choices = $this->choiceList->getChoices(); 94 } catch (\Exception $e) { 95 throw new TransformationFailedException('Can not get the choice list', $e->getCode(), $e); 96 } 97 98 $result = array(); 99 $unknown = array(); 100 101 foreach ($values as $i => $selected) { 102 if ($selected) { 103 if (isset($choices[$i])) { 104 $result[] = $choices[$i]; 105 } else { 106 $unknown[] = $i; 107 } 108 } 109 } 110 111 if (count($unknown) > 0) { 112 throw new TransformationFailedException(sprintf('The choices "%s" were not found', implode('", "', $unknown))); 113 } 114 115 return $result; 116 } 117} 118