Witam.
Próbuję zrobić uploader wg tego co napisał Crozin, jednak po drodze napotkałem problem. Jestem początkujący w Symfony, stąd też mój problem.
Wydaje mi się, że zgubiłem się na tworzeniu listenera.
Serwis:
<service id="my_user.imageupload" class="My\UserBundle\Form\Domain\ImageUpload">
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException"/>
</service>
Listener:
<?php
namespace My\UserBundle\EventListener;
class ImageUploadListener
{
public function __construct()
{
}
public function postBind(FormEvent $event) {
$data = $event->getData();
if (!$data instanceof ImageUpload) {
return;
}
if ($data->getImage()->delete()) {
// usuwamy plik i aktualizujemy nasz obiekt
PropertyAccess::getPropertyAccessor()->setValue($data->getObject(), null);
return;
}
// Tutaj wykonujemy zapis pliku w odpowiednym miejscu, a korzystając z ProeprtyAccess ustawiamy ścieżkę do pliku:
PropertyAccess::getPropertyAccessor()->setValue($data->getObject(), $data->getImagePath());
}
}
Kontroler:
$user = $this->container->get('security.context')->getToken()->getUser();
$data = new ImageUpload($user, new Image(), 'object.avatar');
$form = $this->createForm(new ProfileMainFormType(), $data);
$form->handleRequest($request);
if ($form->isValid()) {
var_dump($form->getData()->getObject());
}
Błąd jaki otrzymuje:
Kod
ContextErrorException: Warning: Missing argument 1 for My\UserBundle\Form\Domain\ImageUpload::__construct(), called in W:\wamp\www\symfony\app\cache\dev\appDevDebugProjectContainer.php on line 2930 and defined in W:\wamp\www\symfony\src\My\UserBundle\Form\Domain\ImageUpload.php line 14
Czy może mnie ktoś nakierować co robię źle?
*********************************************
Edit:
Powoli wraz z dokumentacją Symfony pokonuje trudności napotkane po drodze. Jednak jednego problemu nie mogę pokonać.
Kiedy uploaduje plik, otrzymuje notice
Kod
ContextErrorException: Runtime Notice: Only variables should be passed by reference in W:\wamp\www\symfony\src\My\UserBundle\Form\Type\ProfileAvatarFormType.php line 37
//ProfileAvatarFormType
<?php
namespace My\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\PropertyAccess\PropertyAccess;
use My\UserBundle\Form\Domain\ImageUpload;
class ProfileAvatarFormType extends AbstractType
{
public function buildForm
(FormBuilderInterface
$builder, array $options) {
$builder
->add('avatar', 'file', array('mapped' => false)) ->add('save', 'submit');
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
$data = $event->getData();
if (!$data instanceof ImageUpload) {
return;
}
if ($data->getImage()->getDelete()) {
// usuwamy plik i aktualizujemy nasz obiekt
PropertyAccess::getPropertyAccessor()->setValue($data->getObject(), null);
return;
}
//Tutaj wykonujemy zapis pliku w odpowiednym miejscu, a korzystając z ProeprtyAccess ustawiamy ścieżkę do pliku:
PropertyAccess::getPropertyAccessor()->setValue($data->getObject(), $data->getImagePath());
});
}
public function getName()
{
return 'my_user_profileavatar';
}
}
//Kontroler
public function indexAction(Request $request)
{
$user = $this->container->get('security.context')->getToken()->getUser();
$data = new ImageUpload($user, new Image(), 'avatar');
$form = $this->createForm(new ProfileAvatarFormType(), $data);
$form->handleRequest($request);
if ($form->isValid()) {
$user = $this->container->get('security.context')->getToken()->getUser();
$data = $form->getData();
$userManager = $this->container->get('fos_user.user_manager');
$user->setAvatar($data->getAvatar());
$userManager->updateUser($user);
}
return array('formMain' => $form->createView()); }
//ImageUpload
namespace My\UserBundle\Form\Domain;
use Symfony\Component\Validator\Constraints
as Assert;
class ImageUpload {
/** @Assert\Valid(deep=true) */
private $object;
/** @Assert\Valid(deep=true) */
private $image;
private $imagePath;
public function __construct($object, Image $image, $imagePath) {
$this->object = $object;
$this->image = $image;
$this->imagePath = $imagePath;
}
/**
* @param mixed $image
*/
public function setImage($image)
{
$this->image = $image;
}
/**
* @return mixed
*/
public function getImage()
{
return $this->image;
}
/**
* @param mixed $imagePath
*/
public function setImagePath($imagePath)
{
$this->imagePath = $imagePath;
}
/**
* @return mixed
*/
public function getImagePath()
{
return $this->imagePath;
}
/**
* @param mixed $object
*/
public function setObject($object)
{
$this->object = $object;
}
/**
* @return mixed
*/
public function getObject()
{
return $this->object;
}
}
//Image
<?php
namespace My\UserBundle\Form\Domain;
use Symfony\Component\Validator\Constraints
as Assert;
class Image {
/**
* @Assert\NotBlank
* @Assert\Image(minWidth=50, groups={"UserAvatar"})
* @Assert\Image(minWidth=500, maxWidth=5000, groups={"UserProfile"})
*/
private $file;
/**
* @Assert\Type("boolean")
*/
private $delete = false;
/**
* @param mixed $delete
*/
public function setDelete($delete)
{
$this->delete = $delete;
}
/**
* @return mixed
*/
public function getDelete()
{
return $this->delete;
}
/**
* @param mixed $file
*/
public function setFile($file)
{
$this->file = $file;
}
/**
* @return mixed
*/
public function getFile()
{
return $this->file;
}
}
W PropertyAccessor metoda setValue posiada 3 parametry, jednak Crozin podał tylko 2 (w poprzedniej wersji symfony były 2 parametry?)
public function setValue(&$objectOrArray, $propertyPath, $value)
Wracając do błędu, syfony pokazuje notice gdy przekazuje obiekt w parametrze $objectOrArray, tylko dlaczego?
Kolejna sprawa to jaki powinien być trzeci argument setValue()?
Ten post edytował Crea17 19.02.2014, 23:28:40