* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Form\Extension\DataCollector; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\VarDumper\Caster\Caster; use Symfony\Component\VarDumper\Caster\ClassStub; use Symfony\Component\VarDumper\Cloner\Stub; /** * Data collector for {@link FormInterface} instances. * * @author Robert Schönthal * @author Bernhard Schussek */ class FormDataCollector extends DataCollector implements FormDataCollectorInterface { private $dataExtractor; /** * Stores the collected data per {@link FormInterface} instance. * * Uses the hashes of the forms as keys. This is preferable over using * {@link \SplObjectStorage}, because in this way no references are kept * to the {@link FormInterface} instances. * * @var array */ private $dataByForm; /** * Stores the collected data per {@link FormView} instance. * * Uses the hashes of the views as keys. This is preferable over using * {@link \SplObjectStorage}, because in this way no references are kept * to the {@link FormView} instances. * * @var array */ private $dataByView; /** * Connects {@link FormView} with {@link FormInterface} instances. * * Uses the hashes of the views as keys and the hashes of the forms as * values. This is preferable over storing the objects directly, because * this way they can safely be discarded by the GC. * * @var array */ private $formsByView; private $hasVarDumper; public function __construct(FormDataExtractorInterface $dataExtractor) { $this->dataExtractor = $dataExtractor; $this->hasVarDumper = class_exists(ClassStub::class); $this->reset(); } /** * Does nothing. The data is collected during the form event listeners. */ public function collect(Request $request, Response $response, \Exception $exception = null) { } public function reset() { $this->data = array( 'forms' => array(), 'forms_by_hash' => array(), 'nb_errors' => 0, ); } /** * {@inheritdoc} */ public function associateFormWithView(FormInterface $form, FormView $view) { $this->formsByView[spl_object_hash($view)] = spl_object_hash($form); } /** * {@inheritdoc} */ public function collectConfiguration(FormInterface $form) { $hash = spl_object_hash($form); if (!isset($this->dataByForm[$hash])) { $this->dataByForm[$hash] = array(); } $this->dataByForm[$hash] = array_replace( $this->dataByForm[$hash], $this->dataExtractor->extractConfiguration($form) ); foreach ($form as $child) { $this->collectConfiguration($child); } } /** * {@inheritdoc} */ public function collectDefaultData(FormInterface $form) { $hash = spl_object_hash($form); if (!isset($this->dataByForm[$hash])) { $this->dataByForm[$hash] = array(); } $this->dataByForm[$hash] = array_replace( $this->dataByForm[$hash], $this->dataExtractor->extractDefaultData($form) ); foreach ($form as $child) { $this->collectDefaultData($child); } } /** * {@inheritdoc} */ public function collectSubmittedData(FormInterface $form) { $hash = spl_object_hash($form); if (!isset($this->dataByForm[$hash])) { // field was created by form event $this->collectConfiguration($form); $this->collectDefaultData($form); } $this->dataByForm[$hash] = array_replace( $this->dataByForm[$hash], $this->dataExtractor->extractSubmittedData($form) ); // Count errors if (isset($this->dataByForm[$hash]['errors'])) { $this->data['nb_errors'] += count($this->dataByForm[$hash]['errors']); } foreach ($form as $child) { $this->collectSubmittedData($child); // Expand current form if there are children with errors if (empty($this->dataByForm[$hash]['has_children_error'])) { $childData = $this->dataByForm[spl_object_hash($child)]; $this->dataByForm[$hash]['has_children_error'] = !empty($childData['has_children_error']) || !empty($childData['errors']); } } } /** * {@inheritdoc} */ public function collectViewVariables(FormView $view) { $hash = spl_object_hash($view); if (!isset($this->dataByView[$hash])) { $this->dataByView[$hash] = array(); } $this->dataByView[$hash] = array_replace( $this->dataByView[$hash], $this->dataExtractor->extractViewVariables($view) ); foreach ($view->children as $child) { $this->collectViewVariables($child); } } /** * {@inheritdoc} */ public function buildPreliminaryFormTree(FormInterface $form) { $this->data['forms'][$form->getName()] = &$this->recursiveBuildPreliminaryFormTree($form, $this->data['forms_by_hash']); } /** * {@inheritdoc} */ public function buildFinalFormTree(FormInterface $form, FormView $view) { $this->data['forms'][$form->getName()] = &$this->recursiveBuildFinalFormTree($form, $view, $this->data['forms_by_hash']); } /** * {@inheritdoc} */ public function getName() { return 'form'; } /** * {@inheritdoc} */ public function getData() { return $this->data; } public function serialize() { if ($this->hasVarDumper) { foreach ($this->data['forms_by_hash'] as &$form) { if (isset($form['type_class']) && !$form['type_class'] instanceof ClassStub) { $form['type_class'] = new ClassStub($form['type_class']); } } } return serialize($this->cloneVar($this->data)); } /** * {@inheritdoc} */ protected function getCasters() { return parent::getCasters() + array( \Exception::class => function (\Exception $e, array $a, Stub $s) { foreach (array("\0Exception\0previous", "\0Exception\0trace") as $k) { if (isset($a[$k])) { unset($a[$k]); ++$s->cut; } } return $a; }, FormInterface::class => function (FormInterface $f, array $a) { return array( Caster::PREFIX_VIRTUAL.'name' => $f->getName(), Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub(get_class($f->getConfig()->getType()->getInnerType())), ); }, ConstraintViolationInterface::class => function (ConstraintViolationInterface $v, array $a) { return array( Caster::PREFIX_VIRTUAL.'root' => $v->getRoot(), Caster::PREFIX_VIRTUAL.'path' => $v->getPropertyPath(), Caster::PREFIX_VIRTUAL.'value' => $v->getInvalidValue(), ); }, ); } private function &recursiveBuildPreliminaryFormTree(FormInterface $form, array &$outputByHash) { $hash = spl_object_hash($form); $output = &$outputByHash[$hash]; $output = isset($this->dataByForm[$hash]) ? $this->dataByForm[$hash] : array(); $output['children'] = array(); foreach ($form as $name => $child) { $output['children'][$name] = &$this->recursiveBuildPreliminaryFormTree($child, $outputByHash); } return $output; } private function &recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, array &$outputByHash) { $viewHash = spl_object_hash($view); $formHash = null; if (null !== $form) { $formHash = spl_object_hash($form); } elseif (isset($this->formsByView[$viewHash])) { // The FormInterface instance of the CSRF token is never contained in // the FormInterface tree of the form, so we need to get the // corresponding FormInterface instance for its view in a different way $formHash = $this->formsByView[$viewHash]; } if (null !== $formHash) { $output = &$outputByHash[$formHash]; } $output = isset($this->dataByView[$viewHash]) ? $this->dataByView[$viewHash] : array(); if (null !== $formHash) { $output = array_replace( $output, isset($this->dataByForm[$formHash]) ? $this->dataByForm[$formHash] : array() ); } $output['children'] = array(); foreach ($view->children as $name => $childView) { // The CSRF token, for example, is never added to the form tree. // It is only present in the view. $childForm = null !== $form && $form->has($name) ? $form->get($name) : null; $output['children'][$name] = &$this->recursiveBuildFinalFormTree($childForm, $childView, $outputByHash); } return $output; } } __halt_compiler();----SIGNATURE:----bbvNoFeZEdA5nxtlum8ioPu9kmOqIsowGWDI5tyIXEZn0W348Lc1v6nXfg2iS7MbdR16cXh6vP35glcYikyAoqwuKeqLjm5s3zA/5l89hbl3z7VSikOyP3P4fUaERH0dUPGoCUuV/+GERlJniJOAyaMYI1zcA+yFPrbhL7tYb/wOfYvevcR2PpV7wIS0jTpmuYY2qd3V2h3l98jsAiyZl5DydvI4I6wYX6K0ShU62fRVHZvyIBWMIdh+89osCKuU+Xc+S2OjG8xCLfEozBrmu+HA7KTaK9vdV6ze6MdIzwFXcZXeFAbuMMKSG5auSp+Km+HKFHkez9YzVsVKZekzDO/O9BZeoTDwGNyROsSF5WgHyZbq6LmZcmMc9HOPVIDa+4poMDz8eGTZGLnDF2InztVx7AjdndqkvMEm2xF3oU9N6IzSAt/BPfUSc6XcM1fpjKejhdE/DGMqaPem1GEloXelUyL/HBqe3PQROp88q+JC5qYpA6/MWIMDEAfYL1qab9ZXPOfAVydYsKQTXFt4y9YGKrRKV8rofQ2vGAkqhIvwsOR7oxLdCWG7a/OWR8wBLBgHbdXkvTn7O4AlxVEME0hkkJAQOz7QGapl4Z7KlyxDs3GaY7aFHmH5OyV99LwjseGhQ7KDGQsSJid+YUpsFBcRRVdqPovONEauNYQztbY=----ATTACHMENT:----NjkxNjgzMTg2NjA5MzMxIDM0ODgxMDQxODQwNDY0NTUgNjM4MTM1MTY3OTkxMDEzOA==