/** * Transforms the data to given class via setter and getter methods. * Important: If you pass the `object` param as string, then the class must * be initializable without constructor arguments. * * @param Mapping $mapping The mapping object * @param string|object $object The class name or an object * * @return Mapping */ public function transformTo(Mapping $mapping, $object) { $refl = new \ReflectionClass($object); if (is_string($object)) { $constr = $refl->getConstructor(); if (!$constr || 0 === $constr->getNumberOfRequiredParameters()) { $object = $refl->newInstance(); } else { $object = $refl->newInstanceWithoutConstructor(); } } $mapping->transform(new CallbackTransformer(function ($data) use($refl, $object, $mapping) { if ($object instanceof \stdClass) { return json_decode(json_encode($data)); } foreach ($mapping->getChildren() as $name => $child) { if (array_key_exists($name, $data) && null !== $data[$name]) { $this->setValue($refl, $object, $name, $data[$name]); } } return $object; }, function ($data) use($refl, $object, $mapping) { if (!$data instanceof $object) { return; } if ($object instanceof \stdClass) { return json_decode(json_encode($data), true); } $result = []; foreach ($mapping->getChildren() as $name => $child) { $result[$name] = $this->getValue($refl, $data, $name); } return $result; }, false)); return $mapping; }
/** * Returns a form. * * @param Mapping $mapping The mapping object * * @return Form */ public function form(Mapping $mapping, $path = []) { $children = []; foreach ($mapping->getChildren() as $name => $child) { $children[$name] = $child->form(array_merge($path, [$name])); } $form = new Form($mapping, $children, $path); $emitter = $mapping->getEmitter(); $emitter->on(Events::APPLIED, function (Data $data) use($form) { $form->setData($data->getResult()); $form->setValue($data->getInput()); $form->setErrors($data->getErrors()); }); $emitter->on(Events::UNAPPLIED, function (Data $data) use($form) { $form->setValue($data->getResult()); }); return $form; }