Quantcast
Channel: Active questions tagged symfony4 - Stack Overflow
Viewing all 3924 articles
Browse latest View live

Apply a filter on a SonataAdmin List

$
0
0

I have a backoffice under SonataAdmin and a ForumAdmin class and this class defines a list of fields that are shown in the Forum List template.

Something like that :

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper->addIdentifier('name');
    $listMapper->addIdentifier('description');
    $listMapper->addIdentifier('category');
    $listMapper->addIdentifier('weight');
    $listMapper->addIdentifier('createdAt');
    $listMapper->addIdentifier('updatedAt');
    $listMapper->add('imageName', FileType::class, ['template' => 'Admin/ForumAdmin/image.html.twig']);
}

This works totally fine. I'm getting all the forums with these fields.

But now, I would like to apply by default a filter. I don't want all the forums to appear in the list, but for exemple, only those who have a category (which is an other entity) equals to a specific value.

Is there a way to handle this ? I guess a want to do the same work as the DatagridMapper but I want to do this already before generating the list.

Thanks for your assistance

EDIT: I saw something saying to use the createQuery function

public function createQuery($context = 'list')
{
    $query = parent::createQuery($context);
    $query->andWhere(
        $query->expr()->eq($query->getRootAliases()[0] . '.my_field', ':my_param')
    );
    $query->setParameter('my_param', 'my_value');
    return $query;
}

Problem is :

Method 'andWhere' not found in \Sonata\AdminBundle\Datagrid\ProxyQueryInterface


Symfony validation doesnt' work with Api Platform and action class

$
0
0

I'm using symfony 4 and Api Platform 2.5 . I have created a custom operation to change user password.

The problem is that when I send an empty oldPassword or any other required attributes,the validation doesn't work. As you can see, I used a validation group named "change_password".

This is a part of Entity User :

/**
 * @ApiResource(
 *     itemOperations={
 *         "user_change_password"={
 *             "method"="PUT",
 *             "path"="/users/change-password/{id}",
 *             "controller"=UserChangePassword::class,
 *             "formats"={"json"},
 *             "denormalization_context"={"groups"={"user:change-password"}},
 *             "normalization_context"={"groups"={"user:read"}},
 *             "validation_groups"={"change_password"},
 *             "access_control"="is_granted('EDIT', object)",
 *             "access_control_message"="access denied"
 *         },
 *     },
 * )
 *
 */
class User implements UserInterface, \Serializable, EquatableInterface
{
    /**
     * @Assert\NotBlank(
     *     message="Ancien mot de passe est vide",
     *     groups={"change_password"}
     * )
     * @Groups({"user:change-password"})
     */
    private $oldPassword;

    /**
     * @Assert\NotBlank(
     *     message="Mot de passe ne doit pas être vide",
     *     groups={"registration", "change_password", "change_email"}
     * )
     * @Assert\Length(
     *     min="6",
     *     max="32",
     *     minMessage="Mot de passe doit avoir au minimum ({{ limit }}) caractères.",
     *     maxMessage="Mot de passe doit avoir au maximum ({{ limit }}) caractères.",
     *     groups={"registration", "change_password"}
     * )
     * @Groups({"user:write", "user:change-password"})
     */
    private $plainPassword;

    /**
     * @Assert\NotBlank(
     *     message="Ce champs ne doit pas être vide",
     *     groups={"registration", "change_password"}
     * )
     * @Assert\Expression(
     *     "this.getPlainPassword() == this.getRetypedPlainPassword()",
     *     message="Mots de passe ne sont pas identiques",
     *     groups={"registration", "change_password"}
     * )
     * @Groups({"user:write", "user:change-password"})
     */
    private $retypedPlainPassword;

}

This is the custom operation class :

class UserChangePassword
{


    public function __invoke(User $data)
    {
        $errors = $this->validator->validate($data);
        if (count($errors) > 0) {
            throw new ValidationException($errors);
        }

        dd($errors) ;

        $oldPassword = $data->getOldPassword();
        if ($this->passwordEncoder->isPasswordValid($data, $oldPassword)) {
            // do changes
        }

    return $data;

    }
}

The output of dd($erros) when the oldPassword is empty :

enter image description here

And without dd($erros) I get this error :

enter image description here

Fatal error: Uncaught Twig\Error\LoaderError

$
0
0

I have just deployed my application on the server. If I use APP_ENV=dev, everything works fine but if I use APP_ENV=prod, I get the following error:

Fatal error: Uncaught Twig\Error\LoaderError: The "/home/httpd/vhosts/example.com/httpdocs/api_tapalle\vendor\symfony\framework-bundle/Resources/views" directory does not exist ("/home/httpd/vhosts/example.com/httpdocs/api_tapalle\vendor\symfony\framework-bundle/Resources/views"). in /home/httpd/vhosts/example.com/httpdocs/api_tapalle/vendor/twig/twig/src/Loader/FilesystemLoader.php:106 Stack trace: #0 /home/httpd/vhosts/example.com/httpdocs/api_tapalle/var/cache/prod/ContainerTP5linE/srcApp_KernelProdContainer.php(471): Twig\Loader\FilesystemLoader->addPath('/home/httpd/vho...', 'Framework') #1 /home/httpd/vhosts/example.com/httpdocs/api_tapalle/var/cache/prod/ContainerTP5linE/srcApp_KernelProdContainer.php(729): ContainerTP5linE\srcApp_KernelProdContainer->getTwigService() #2 /home/httpd/vhosts/example.com/httpdocs/api_tapalle/var/cache/prod/ContainerTP5linE/srcApp_KernelProdContainer.php(346): ContainerTP5linE\srcApp_KernelProdContainer->getSensioFrameworkExtra_View_ListenerService() #3 /home/httpd/vhosts/y in /home/httpd/vhosts/example.com/httpdocs/api_tapalle/vendor/twig/twig/src/Loader/FilesystemLoader.php on line 106

Since I have this error, I have used php bin/console cache:clear -e prod to clear the cache and then uploaded var and vendor directories again.

The weird thing is that vendor\symfony\framework-bundle/Resources/views and vendor/twig/twig/src/Loader/FilesystemLoader.php exist on the server!

Why do I get this error?

Cannot execute bin/console doctrine:migrations:migrate RuntimeException /vendor/symfony/console/Helper/QuestionHelper.php:129

$
0
0

I am deploying my Symfony 4 app to the production environment for the first time using rsync.

I then try to run the doctrine:migrations:migrate command.

php -v : PHP 5.6.40

CentOS: 7.6

EasyApache4

When I execute:

bin/console doctrine:migrations:migrate

I received the following error:

Fatal error: Default value for parameters with a class type hint can only be NULL in /home/simpleit/ch.simpleitsolutions.bookings/vendor/symfony/console/Application.php on line 85

I understand that Symfony 4 DoctrineMigrationsBundle requires PHP 7.1 so I also tried the following:

/usr/bin/ea-php71 bin/console doctrine:migrations:migrate

And I received the following error:

WARNING! You are about to execute a database migration that could result in schema changes and data loss. Are you sure you wish to continue? (y/n)[2019-02-10 12:10:52] console.ERROR: Error thrown while running command "{command}". Message: "{message}" {"exception":"[object] (Symfony\\Component\\Console\\Exception\\RuntimeException(code: 0): Aborted at /home/<account_dir>/vendor/symfony/console/Helper/QuestionHelper.php:129)","command":"doctrine:migrations:migrate","message":"Aborted"} []

Thank you in advance

Swiftmailler through Proxy

$
0
0

In my development env I did this small code to test to send emails.

$message = (new \Swift_Message('Hello Email'))
    ->setFrom('sendTest@mysender.com')
    ->setTo('myEmail@gmail.com')
    ->setBody($this->container->get('twig')->render('emails/test_email.html.twig'),
        'text/html'
    );
$this->mailer->send($message);

It's works well.

My issue is in the Prod environment my server must use a proxy to access to internet.

this is the message I get:

[app] Exception occurred while flushing email queue: Connection could not be established with host **** [A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

I didn't find the way in Swiftmailler documentation to setup the proxy... someone already do it ? :)

thank you

monolog catch Fatal Error: Allowed memory size exhausted

$
0
0

I would like to know how I can make monolog for symfony 4 logging fatal errors:

 PHP Fatal error: Allowed memory size of xxxx exhausted

to the main log handler.

In my application these errors are logged in the PHP error_log file.

Symfony 5 pass parameter to logout / login functions

$
0
0

In a Symfony 5.0 Application I have the following scenario:

An admin user is able to create new users. If a new user is created in that way I want to log out the admin redirect to the login screen and set the prefilled value in the email field to the one of the user created just before.

Currently I have a link with href="{{ path('app_logout', {email: user.email}) }}" I the SecurityController I got the default logout method defined like this

/**
 * @Route("/logout", name="app_logout")
 */
public function logout()
{
    throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
}

So... how would I be able to process the "email"-parameter and pass it on to the login function to handle it there?

Symfony validation doesnt' work with Api Platform when using custom action class

$
0
0

I'm using symfony 4 and Api Platform 2.5 . I have created a custom operation to change user password.

The problem is that when I send an empty oldPassword or any other required attributes,the validation doesn't work. As you can see, I used a validation group named "change_password".

This is a part of Entity User :

/**
 * @ApiResource(
 *     itemOperations={
 *         "user_change_password"={
 *             "method"="PUT",
 *             "path"="/users/change-password/{id}",
 *             "controller"=UserChangePassword::class,
 *             "formats"={"json"},
 *             "denormalization_context"={"groups"={"user:change-password"}},
 *             "normalization_context"={"groups"={"user:read"}},
 *             "validation_groups"={"change_password"},
 *             "access_control"="is_granted('EDIT', object)",
 *             "access_control_message"="access denied"
 *         },
 *     },
 * )
 *
 */
class User implements UserInterface, \Serializable, EquatableInterface
{
    /**
     * @Assert\NotBlank(
     *     message=Tthis value should not be blank",
     *     groups={"change_password"}
     * )
     * @SecurityAssert\UserPassword(
     *     message = "Wrong value for your current password",
     *     groups={"change_password"}
     * )
     * @Groups({"user:change-password"})
     */
    private $oldPassword;

    /**
     * @Assert\NotBlank(
     *     message="This value should not be blank",
     *     groups={"registration", "change_password"}
     * )
     * @Assert\Length(
     *     min="6",
     *     max="32",
     *     minMessage="Password must be at least ({{ limit }}) characters.",
     *     maxMessage="Password must have a maximum of ({{ limit }}) characters.",
     *     groups={"registration", "change_password"}
     * )
     * @Groups({"user:write", "user:change-password"})
     */
    private $plainPassword;

    /**
     * @Assert\NotBlank(
     *     message="This value should not be blank",
     *     groups={"registration", "change_password"}
     * )
     * @Assert\Expression(
     *     "this.getPlainPassword() == this.getRetypedPlainPassword()",
     *     groups={"registration", "change_password"}
     * )
     * @Groups({"user:write", "user:change-password"})
     */
    private $retypedPlainPassword;

}

This is the custom operation class :

class UserChangePassword
{

    public function __invoke(User $data)
    {
        $errors = $this->validator->validate($data);
        if (count($errors) > 0) {
            throw new ValidationException($errors);
        }

        dd($errors) ;

        $oldPassword = $data->getOldPassword();
        if ($this->passwordEncoder->isPasswordValid($data, $oldPassword)) {
            // do changes
        }

        return $data;

    }
}

The output of dd($erros) when the oldPassword is empty :

enter image description here

And without dd($erros) I get this error :

enter image description here


Symfony 4 - cannot find all migration versions

$
0
0

I am trying to run migrations on a Symfony 4 application with a total of 271 migrations. However, when doing so it skips the first 41 migrations (the first is Version20180921083101).

>>> php bin/console doctrine:migrations:status

 == Configuration

    >> Name:                                               Application Migrations
    >> Database Driver:                                    pdo_mysql
    >> Database Host:                                      db
    >> Database Name:                                      test
    >> Configuration Source:                               manually configured
    >> Version Table Name:                                 migration_versions
    >> Version Column Name:                                version
    >> Migrations Namespace:                               DoctrineMigrations
    >> Migrations Directory:                               /var/www/src/Migrations
    >> Previous Version:                                   Already at first version
    >> Current Version:                                    0
    >> Next Version:                                       2018-11-14 06:38:03 (20181114063803)
    >> Latest Version:                                     2020-01-27 05:06:49 (20200127050649)
    >> Executed Migrations:                                0
    >> Executed Unavailable Migrations:                    0
    >> Available Migrations:                               230
    >> New Migrations:                                     230

I am been trying to update the schema, clear cache, and dropped/recreated the database, but without success. I have also tried to execute only the first one by running the following command:

>>> php bin/console doctrine:migrations:migrate Version20180921083101

                    Application Migrations


Unknown version: Version20180921083101

It seems that those versions prior to Version20181114063803 cannot be recognized. I have been struggling with this issue for a while now and running out of things to try so any help or pointers would be highly appreciated. Thanks!

Symfony Easyadmin - How to open modal on custom action

$
0
0

I'm trying to create a custom action with the type 'route'. But I want to display a confirmation modal before doing the request. For example, in the list view, I want to have the actions: edit, view and publish. But when the user presses publish, I want a confirmation modal.

This behavior already occurs with the delete action, but I can't seem to understand how to replicate it to a custom action.

Any ideas?

Thank you

Symfony 5 preserve session attribute after user logout

$
0
0

In https://symfony.com/doc/current/session.html it is said that "Stored attributes remain in the session for the remainder of that user's session."

Is there a way to keep session attributes when the user gets loged out? If this is not ment to happen - how would I keep information over user login/logout/switches?

Create a session from API

$
0
0

My frontend is on example.com and my backend is on api.example.com.

I am using this line to set a session:

$this->get('session')->set('id', 1);

I can get the value of that session by using:

$this->get('session')->get('id');

That works but it only works if both lines are in the same function. If you try to get the value of that session in another function, it returns NULL. So what I am trying to say is that the session is not getting stored. I am not sure but maybe it is not getting stored, because the user is basically not on api.example.com but on example.com. Could that be the reason? If so, is there another way to store a value, so that it can be used in other functions?

Session can not be saved

$
0
0

From one function I am setting a session and from another function, I would like to get the value of that session.

// Set the session
public function setSession($data) {
    $this->get('session')->set('id', $this->loginDao->getId($data['email']));
    return true;
}
// Get the session
public function getSession() {
    return new Response(json_encode($this->get('session')->get('id')));
}

My problem is that getSession returns null.

I have tested it with Postman and that works! What I have realized is that Postman has PHPSESSID=1a2714euatml19jj4p1rq9sbsa as Cookie in header but in Chrome it's missing.

This is how the header looks like in Chrome:

enter image description here

Correct me if I am wrong, but I guess Set-Cookie is missing here.

However, what is the reason that it works in Postman but not in the browser? And how can I fix this?

Symfony / Doctrine : problem with an entity ManyToOne to OneToOne

$
0
0

I'm having troubles with my Users entity.

In my website, users can fill their collection to keep track of their Magic the gathering cards. Every users have one and only one collection. So, I created a table "Collection", mapped in OneToOne between Users and Collection.

This table collection is mapped to a another table named "CollectionContent" in ManyToOne. This table contains only one field, quantity. I created this table because the ManyToMany association doesn't allow additionnals fields.

The table collectionContent is then mapped to Cards in ManyToOne. (to simulate the ManyToMany with an additional field.)

Here comes the problem : I made a mistake while creating the entity at first and created it as ManyToOne between users and Collection. (instead of OneToOne)

And now, I'm trying to call

$userCollectionId = $this->getUser()->getCollection();

Which should return the user collection id, and I get an error message :

Return value of App\Entity\Users::getCollection() must implement interface Doctrine\Common\Collections\Collection, instance of App\Entity\Collections returned

I guess there are two possibilities :

  • I cant name my entity 'Collection' ? is it a reserved word or something ?
  • The methods to get the collection from the user arent good anymore because I changed the ManyToOne into OneToOne and I have to delete something, but I dont know exactly what.

Here's my Users Entity :

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="App\Repository\UsersRepository")
 * @UniqueEntity(
 *     fields={"email"},
 *     message="L'adresse mail est déjà utilisée."
 * )
 */
class Users implements UserInterface
{

    private const DEFAULT_IMAGE = "default.jpg";
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, unique=true)
     * @Assert\Length(min="5", minMessage="Votre pseudo doit faire plus de 4 caractères")
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Length(min="6", minMessage="Votre mot de passe doit faire plus de 5 caractères")
     */
    private $password;

    /**
     * @ORM\Column(type="string", length=255, unique=true)
     * @Assert\Email()
     */
    private $email;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $firstName;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $lastName;

    /**
     * @ORM\Column(type="json")
     */
    private $roles = [];

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Collections", mappedBy="users", orphanRemoval=true)
     */
    private $collection;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Wishlists", mappedBy="users")
     */
    private $wishlists;

    /**
     * @ORM\Column(type="datetime", options={"default" : "CURRENT_TIMESTAMP"})
     */
    private $registeredAt;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Comments", mappedBy="auteur", orphanRemoval=true)
     */
    private $comments;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Comments", mappedBy="postedOnUser")
     */
    private $commentsOnUser;

    /**
     * @ORM\Column(type="string", length=255, nullable=true, options={"default" : "default.jpg"})
     */
    private $image;

    public function __construct()
    {
        $this->collection = new ArrayCollection();
        $this->wishlists = new ArrayCollection();
        $this->comments = new ArrayCollection();
        $this->commentsOnUser = new ArrayCollection();
    }


    public function getId(): ?int
    {
        return $this->id;
    }

    public function getUsername(): ?string
    {
        return $this->username;
    }

    public function setUsername(string $username): self
    {
        $this->username = $username;

        return $this;
    }

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getFirstName(): ?string
    {
        return $this->firstName;
    }

    public function setFirstName(string $firstName): self
    {
        $this->firstName = $firstName;

        return $this;
    }

    public function getLastName(): ?string
    {
        return $this->lastName;
    }

    public function setLastName(string $lastName): self
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getRoles(): array
    {
        $role = $this->roles;
        // guarantee every user at least has ROLE_USER
        $role[] = 'ROLE_USER';

        return array_unique($role);
    }

    public function setRole(array $role): self
    {
        $this->roles = $role;

        return $this;
    }

    /**
     * @return Collection|collections[]
     */
    public function getCollection(): Collection
    {
        return $this->collection;
    }

    public function addCollection(collections $collection): self
    {
        if (!$this->collection->contains($collection)) {
            $this->collection[] = $collection;
            $collection->setUsers($this);
        }

        return $this;
    }

    public function removeCollection(collections $collection): self
    {
        if ($this->collection->contains($collection)) {
            $this->collection->removeElement($collection);
            // set the owning side to null (unless already changed)
            if ($collection->getUsers() === $this) {
                $collection->setUsers(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|wishlists[]
     */
    public function getWishlists(): Collection
    {
        return $this->wishlists;
    }

    public function addWishlist(wishlists $wishlist): self
    {
        if (!$this->wishlists->contains($wishlist)) {
            $this->wishlists[] = $wishlist;
            $wishlist->setUsers($this);
        }

        return $this;
    }

    public function removeWishlist(wishlists $wishlist): self
    {
        if ($this->wishlists->contains($wishlist)) {
            $this->wishlists->removeElement($wishlist);
            // set the owning side to null (unless already changed)
            if ($wishlist->getUsers() === $this) {
                $wishlist->setUsers(null);
            }
        }

        return $this;
    }

    public function getRegisteredAt(): ?\DateTimeInterface
    {
        return $this->registeredAt;
    }

    public function setRegisteredAt(\DateTimeInterface $registeredAt): self
    {
        $this->registeredAt = $registeredAt;

        return $this;
    }

    /**
     * @return Collection|Comments[]
     */
    public function getComments(): Collection
    {
        return $this->comments;
    }

    public function addComment(Comments $comment): self
    {
        if (!$this->comments->contains($comment)) {
            $this->comments[] = $comment;
            $comment->setAuteur($this);
        }

        return $this;
    }

    public function removeComment(Comments $comment): self
    {
        if ($this->comments->contains($comment)) {
            $this->comments->removeElement($comment);
            // set the owning side to null (unless already changed)
            if ($comment->getAuteur() === $this) {
                $comment->setAuteur(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Comments[]
     */
    public function getCommentsOnUser(): Collection
    {
        return $this->commentsOnUser;
    }

    public function addCommentsOnUser(Comments $commentsOnUser): self
    {
        if (!$this->commentsOnUser->contains($commentsOnUser)) {
            $this->commentsOnUser[] = $commentsOnUser;
            $commentsOnUser->setPostedOnUser($this);
        }

        return $this;
    }

    public function removeCommentsOnUser(Comments $commentsOnUser): self
    {
        if ($this->commentsOnUser->contains($commentsOnUser)) {
            $this->commentsOnUser->removeElement($commentsOnUser);
            // set the owning side to null (unless already changed)
            if ($commentsOnUser->getPostedOnUser() === $this) {
                $commentsOnUser->setPostedOnUser(null);
            }
        }

        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getSalt()
    {
        // TODO: Implement getSalt() method.
    }

    /**
     * @inheritDoc
     */
    public function eraseCredentials()
    {
        // TODO: Implement eraseCredentials() method.
    }

    public function getImage(): ?string
    {
        return $this->image;
    }

    public function setImage(?string $image): self
    {
        $this->image = $image;

        return $this;
    }
}

How to add role on user during the session

$
0
0

I just updated Symfony 4.3 to 4.4 and since, when I modify the role of my user after my login page, this one is disconnected

Before I did this in my controller:

$this->getUser()->setRoles(['ROLE_MODERATEUR']);

Everything went well, there was no disconnection.

But since version 4.4, the user systematically loses his session.

Does anyone have a solution to bring me to resolve my concerns?

Thank you in advance.


How to get project directory from Symfony 4

$
0
0

What I need is the project directory or the public directory from symfony.

use App\Kernel;

class FileReader
{
    public function __construct(
       Kernel $kernel
    )
    {
        var_dump ($kernel->getProjectDir());

    }
}

The problem is I can not inject the kernel to my class.

In this post there are several strange things for me.

First, I get this error:

Cannot autowire service "App\Utils\Lotto\FileReader": argument "$kernel" of method "__construct()" references class "App\Kernel" but no such service exists. Try changing the type-hint to one of its parents: interface "Symfony\Component\HttpKernel\HttpKernelInterface", or interface "Symfony\Component\HttpKernel\KernelInterface".

Second, I have no KernelInterface from PHPStorm autocomplete, those interface is only for HttpKernelInterface what has no getProjectDirectory method.

How can I read out the /var/www/myproject or /var/www/myproject/public/?

Truncate string in Symfony Controller?

$
0
0

Is there a way to truncate a string directly in the controller?

Something like:

'description' => $result->getDescription()->truncate(80),

Symfony 4 handling null DateType form field

$
0
0

I have a form in Symfony 4 where I implement the DateType as a text field

->add('DateOfBirth', DateType::class, array(
    'required' => false,
    'widget' => 'single_text',
    'empty_data' =
))

however the field is optional to fill in for the form. When I submit the form with an empty value for that field I receive the error:

Expected argument of type "DateTimeInterface", "NULL" given.

erroring on the line

$form->handleRequest($request);

It seems I need to pass in a default value (i.e. - 1/1/1990) as null is not a valid DateTime value? What is the correct way to handle this? I looked on this page and tried various things (i.e. - changing input type) but nothing seems to fix this.

Thanks in advance!

My Entity:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use NoProtocol\Encryption\MySQL\AES\Crypter;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PatientsRepository")
 * @ORM\Table(name="Patients")
 */
class PatientSearch
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="integer")
     */
    private $PatientId;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private $Address1;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private $Address2;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     */
    private $City;

    /**
     * @ORM\Column(type="string", length=2, nullable=true)
     */
    private $State;

    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private $DateOfBirth;

    /**
     * @ORM\Column(type="string", length=50)
     */
    private $LastName;

    /**
     * @ORM\Column(type="string", length=50)
     */
    private $FirstName;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getPatientId(): ?int
    {
        return $this->PatientId;
    }

    public function setPatientId(int $PatientId): self
    {
        $this->PatientId = $PatientId;

        return $this;
    }

    public function getAddress1(): ?string
    {
        return $this->Address1;
    }

    public function setAddress1(string $Address1): self
    {
        $this->Address1 = $Address1;

        return $this;
    }

    public function getAddress2(): ?string
    {
        return $this->Address2;
    }

    public function setAddress2(string $Address2): self
    {
        $this->Address2 = $Address2;

        return $this;
    }

    public function getCity(): ?string
    {
        return $this->City;
    }

    public function setCity(string $City): self
    {
        $this->City = $City;

        return $this;
    }

    public function getState(): ?string
    {
        return $this->State;
    }

    public function setState(string $State): self
    {
        $this->State = $State;

        return $this;
    }

    public function getDateOfBirth(): ?\DateTimeInterface
    {
        return $this->DateOfBirth;
    }

    public function setDateOfBirth(\DateTimeInterface $DateOfBirth): self
    {
        $this->DateOfBirth = $DateOfBirth;

        return $this;
    }

    public function getLastName(): ?string
    {
        return $this->LastName;
    }

    public function setLastName(string $LastName): self
    {
        $this->LastName = $LastName;

        return $this;
    }

    public function getFirstName(): ?string
    {
        return $this->FirstName;
    }

    public function setFirstName(string $FirstName): self
    {
        $this->FirstName = $FirstName;

        return $this;
    }
}

Type:

<?php

namespace App\Form;

use App\Entity\PatientSearch;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PatientSearchType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('FirstName', TextType::class, array('required' => false))
            ->add('LastName', TextType::class, array('required' => false))
            ->add('DateOfBirth', DateType::class, array(
                'required' => false,
                'widget' => 'single_text',
                'empty_data'  => '',
                ))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => PatientSearch::class,
        ]);
    }
}

Controller:

<?php

namespace App\Controller;

use App\Form\PatientSearchType;
use App\Entity\PatientSearch;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;

class PatientSearchController extends AbstractController
{
    /**
     * @Route("/patient/search", name="patient_search")
     */
    public function index(Request $request)
    {
        $form = $this->createForm(PatientSearchType::class);

        $form->handleRequest($request);

        dump($form);
        dump($form->isValid());

        $search = null;
        if ($form->isSubmitted() && $form->isValid()) {
            $searchFormData = $form->getData();
            dump($searchFormData);
            $search = $this->getDoctrine()
                ->getRepository(PatientSearch::class)
                ->findBy(array(
                    'LastName' => $searchFormData->getLastName(),
                    'FirstName' => $searchFormData->getFirstName(),
                    'DateOfBirth' => $searchFormData->getDateOfBirth(),
                    ));

        }

        return $this->render('patient_search/index.html.twig', [
            'search_form' => $form->createView(),
            'search' => $search
        ]);
    }
}

Error Dump (after setting 'empty_data' =>'1/1/2000)':

FormErrorIterator {#542 ▼
  -form: Form {#507 ▼
    -config: FormBuilder {#508 ▶}
    -parent: null
    -children: OrderedHashMap {#509 ▼
      -elements: array:3 [▼
        "FirstName" => Form {#510 ▶}
        "LastName" => Form {#513 ▶}
        "DateOfBirth" => Form {#516 ▼
          -config: FormBuilder {#517 ▶}
          -parent: Form {#507}
          -children: OrderedHashMap {#518 ▶}
          -errors: array:1 [▼
            0 => FormError {#825 ▼
              #messageTemplate: "This value is not valid."
              #messageParameters: array:1 [▼
                "{{ value }}" => "1/1/2000"
              ]
              #messagePluralization: null
              -message: "This value is not valid."
              -cause: ConstraintViolation {#794 ▼
                -message: "This value is not valid."
                -messageTemplate: "This value is not valid."
                -parameters: array:1 [▶]
                -plural: null
                -root: Form {#507}
                -propertyPath: "children[DateOfBirth]"
                -invalidValue: "1/1/2000"
                -constraint: Form {#532 ▶}
                -code: "1dafa156-89e1-4736-b832-419c2e501fca"
                -cause: TransformationFailedException {#520 ▶}
              }
              -origin: Form {#516}
            }
          ]
          -submitted: true
          -clickedButton: null
          -modelData: null
          -normData: null
          -viewData: "1/1/2000"
          -extraData: []
          -transformationFailure: TransformationFailedException {#520 ▼
            #message: "Unable to reverse value for property path "DateOfBirth": Date parsing failed: U_PARSE_ERROR"
            #code: 0
            #file: "/mnt/c/Users/ElementZero/source/php/phleb-manager/vendor/symfony/form/Form.php"
            #line: 1137
            -previous: TransformationFailedException {#523 ▶}
            trace: {▶}
          }
          -defaultDataSet: true
          -lockSetData: false
        }
      ]
      -orderedKeys: array:3 [▶]
      -managedCursors: []
    }
    -errors: []
    -submitted: true
    -clickedButton: null
    -modelData: PatientSearch {#501 ▶}
    -normData: PatientSearch {#501 ▶}
    -viewData: PatientSearch {#501 ▶}
    -extraData: []
    -transformationFailure: null
    -defaultDataSet: true
    -lockSetData: false
  }
  -errors: []
}

Normalize virtual property with API Platform

$
0
0

I'm trying to return a virtual property with API Platform, but the only thing that I can get is the IRI.

I have multiple User, linked to multiple Organization. Those Organization have only one "Owner" (User class).

I want a property named "coach" which return the Owner of the first Organization

The case is a bit more complex but I simplified it.

App\Entity\User

/**
 * @ApiResource(
 *      itemOperations={
 *          "get"={"security"="is_granted('view', object)"},
 *      },
 *      normalizationContext={"groups"={"user", "user:read"}},
 *      denormalizationContext={"groups"={"user", "user:write"}}
 * )
 * @ORM\Table(name="user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @Groups({"user"})
     */
    protected $email;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Groups({"user"})
     */
    private $firstName;

    /**
     * @ApiProperty()
     * @Groups({"user"})
     */
    private $coach;

    /**
     * User constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->organizations = new ArrayCollection();
    }

    [...]

    public function getCoach(): ?User
    {
        $coach = null;
        if (count($this->getOrganizations()) > 0) {
            $coach = $this->getOrganizations()->first()->getOwnerUser();
        }

        return $coach;
    }
}

I still getting

{
    email: xxx;
    firstName: xxx;
    organizations: [
       {
          name: xxx;
       },
       {
          name: xxx;
       }
    ],
    coach: "/api/users/4"
}

and I would like a proper User like

{
    email: xxx;
    firstName: xxx;
    organizations: [
       {
          name: xxx;
       },
       {
          name: xxx;
       }
    ],
    coach: {
       email: xxx;
       firstName: xxx;
    }
 }

Call to function getContainer on null in SonataAdmin

$
0
0

I'm trying to make some custom things over SonataAdmin in order to make it suit my needs.

I have an abstract class extending the default AbstractAdmin from Sonata. In this abstract class there are other methods, but the one triggering an error is this one

abstract class SecureAdmin extends AbstractAdmin implements CustomDataInterface

    public function getCurrentUser()
    {
        return $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser();
    }

Call to function getContainer on null

That means getConfigurationPool() is null but why ?

CustomDataInterface only contains methods declaration that need to be used in the concrete implementation of SecureAdmin so I guess it's irrelevant here.

In the concrete implementation I will have something like that

class SiteAdmin extends SecureAdmin
{

    private $adminname = "Site";

    /**
     * @var $current_user
     */
    private $current_user;

    public function __construct($code, $class, $baseControllerName)
    {
        parent::__construct($code, $class, $baseControllerName);
        $this->current_user = $this->getCurrentUser();

    }
}

Thanks for your assistance.

Viewing all 3924 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>