phpsymfonyvalidationentity

Symfony2 Validation against multiple fields


I have a contestEntry entity.

It has a number of properties (player Positions) all linking to a fantasyPlayer entity.

On submission of a form i need to check that the different player positions are unique (ie a player has not been put in 2 positions)

Is it possible to use validations for this, as far i can see i can only apply a validation to a property, is there a way to apply validations across the whole entity?

ContestEntry:

<?php
namespace FantasyPro\GameBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use FantasyPro\DataBundle\Entity\DailyFantasyPlayer;
use FantasyPro\UserBundle\Entity\User;

/**
 * @ORM\Entity(repositoryClass="FantasyPro\GameBundle\Entity\ContestEntryRepository")
 * @ORM\Table(name="fp_contestEntry")
 */
class ContestEntry
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="boolean", nullable=true, name="locked")
     */
    private $locked;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\UserBundle\Entity\User", inversedBy="contestEntries")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="qb", referencedColumnName="id")
     */
    private $qb;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="wr1", referencedColumnName="id")
     */
    private $wr1;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="wr2", referencedColumnName="id")
     */
    private $wr2;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="rb1", referencedColumnName="id")
     */
    private $rb1;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="rb2", referencedColumnName="id")
     */
    private $rb2;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="te", referencedColumnName="id")
     */
    private $te;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="k", referencedColumnName="id")
     */
    private $k;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="flex", referencedColumnName="id")
     */
    private $flex;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\DailyFantasyPlayer")
     * @ORM\JoinColumn(name="def", referencedColumnName="id")
     */
    private $def;

    /**
     * @ORM\ManyToOne(targetEntity="FantasyPro\GameBundle\Entity\Contest", inversedBy="contestEntries")
     * @ORM\JoinColumn(name="contest", referencedColumnName="id")
     */
    private $contest;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set locked
     *
     * @param boolean $locked
     *
     * @return ContestEntry
     */
    public function setLocked($locked)
    {
        $this->locked = $locked;

        return $this;
    }

    /**
     * Get locked
     *
     * @return boolean
     */
    public function getLocked()
    {
        return $this->locked;
    }

    /**
     * Set user
     *
     * @param \FantasyPro\UserBundle\Entity\User $user
     *
     * @return ContestEntry
     */
    public function setUser(User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \FantasyPro\UserBundle\Entity\User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Set qb
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $qb
     *
     * @return ContestEntry
     */
    public function setQb(DailyFantasyPlayer $qb = null)
    {
        $this->qb = $qb;

        return $this;
    }

    /**
     * Get qb
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getQb()
    {
        return $this->qb;
    }

    /**
     * Set wr1
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $wr1
     *
     * @return ContestEntry
     */
    public function setWr1(DailyFantasyPlayer $wr1 = null)
    {
        $this->wr1 = $wr1;

        return $this;
    }

    /**
     * Get wr1
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getWr1()
    {
        return $this->wr1;
    }

    /**
     * Set wr2
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $wr2
     *
     * @return ContestEntry
     */
    public function setWr2(DailyFantasyPlayer $wr2 = null)
    {
        $this->wr2 = $wr2;

        return $this;
    }

    /**
     * Get wr2
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getWr2()
    {
        return $this->wr2;
    }

    /**
     * Set rb1
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $rb1
     *
     * @return ContestEntry
     */
    public function setRb1(DailyFantasyPlayer $rb1 = null)
    {
        $this->rb1 = $rb1;

        return $this;
    }

    /**
     * Get rb1
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getRb1()
    {
        return $this->rb1;
    }

    /**
     * Set rb2
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $rb2
     *
     * @return ContestEntry
     */
    public function setRb2(DailyFantasyPlayer $rb2 = null)
    {
        $this->rb2 = $rb2;

        return $this;
    }

    /**
     * Get rb2
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getRb2()
    {
        return $this->rb2;
    }

    /**
     * Set te
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $te
     *
     * @return ContestEntry
     */
    public function setTe(DailyFantasyPlayer $te = null)
    {
        $this->te = $te;

        return $this;
    }

    /**
     * Get te
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getTe()
    {
        return $this->te;
    }

    /**
     * Set k
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $k
     *
     * @return ContestEntry
     */
    public function setK(DailyFantasyPlayer $k = null)
    {
        $this->k = $k;

        return $this;
    }

    /**
     * Get k
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getK()
    {
        return $this->k;
    }

    /**
     * Set flex
     *
     * @param \FantasyPro\DataBundle\Entity\DailyFantasyPlayer $flex
     *
     * @return ContestEntry
     */
    public function setFlex(DailyFantasyPlayer $flex = null)
    {
        $this->flex = $flex;

        return $this;
    }

    /**
     * Get flex
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getFlex()
    {
        return $this->flex;
    }

    /**
     * Set def
     *
     * @param DailyFantasyPlayer $def
     *
     * @return ContestEntry
     */
    public function setDef(DailyFantasyPlayer $def = null)
    {
        $this->def = $def;

        return $this;
    }

    /**
     * Get def
     *
     * @return \FantasyPro\DataBundle\Entity\DailyFantasyPlayer
     */
    public function getDef()
    {
        return $this->def;
    }

    /**
     * Set contest
     *
     * @param \FantasyPro\GameBundle\Entity\Contest $contest
     *
     * @return ContestEntry
     */
    public function setContest(Contest $contest = null)
    {
        $this->contest = $contest;

        return $this;
    }

    /**
     * Get contest
     *
     * @return \FantasyPro\GameBundle\Entity\Contest
     */
    public function getContest()
    {
        return $this->contest;
    }
}

I have a contestHelper class containing various methods, one of them is to check that the selected fantasyPlayers are unique

/**
     * Checks to see that the players selected for the squad are unique
     * i.e no player/team has been selected twice
     *
     * @param ContestEntry $contestEntry
     *
     * @return bool
     */
    public function squadPlayersAreUnique( ContestEntry $contestEntry )
    {
        //checks to see there are no duplicate players in the squad
        $playerArray = array(
            $contestEntry->getWr1()->getPlayer()->getId(),
            $contestEntry->getWr2()->getPlayer()->getId(),
            $contestEntry->getRb1()->getPlayer()->getId(),
            $contestEntry->getRb2()->getPlayer()->getId(),
            $contestEntry->getTe()->getPlayer()->getId(),
            $contestEntry->getK()->getPlayer()->getId(),
            $contestEntry->getFlex()->getPlayer()->getId(),
            $contestEntry->getDef()->getTeam()->getPlayerID()
        );
        return count( $playerArray ) == count( array_unique( $playerArray ) );
    }

My controller is very wrong as i have a call to squadPlayersAreUnique within my validation controller, and no way to redirect properly back to the page.

Is there a way to add this validation to the entire entity itself?

heres my controller in its current state:

/**
     * Shows a form for Updating a contestEntry.
     *
     * @Route("/manageentry/{id}", name="update_contestentry")
     * @Template("GameBundle:ContestEntry:update.html.twig")
     * @param ContestEntry $contestEntry
     * @ParamConverter("contestEntry", class="GameBundle:ContestEntry", options={"id" = "id"})
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function updateEntryAction( ContestEntry $contestEntry = null )
    {
        $session = new Session();
        $session->start();

        // add flash messages

        if ( empty( $contestEntry)) {
            //$session->getFlashBag()->add('error', 'Sorry, We could not find your contest entry!');
            throw $this->createNotFoundException(
                'Sorry, We could not find your contest entry!'
            );
        }
        $request = Request::createFromGlobals();

        $contestHelper = $this->get( 'contest_helper' );

        $contest = $contestEntry->getContest();

        $availablePlayers = $contestHelper->getPlayersforContestResult( $contest );

        $form = $this->createForm( 'contestEntry', $contestEntry );

        $form->handleRequest( $request );

        if ($form->isValid()) {
            //check there are no duplicate players
            if( !$contestHelper->squadPlayersAreUnique( $contestEntry ) ){
                //throw new HttpException(500, 'Duplicate players found in your squad!');
                $session->getFlashBag()->add('error', 'Duplicate players found in your squad, Please check your entry and try again!');
            }

            if( !$contestHelper->entryNotOverBudget( $contestEntry) ){
               // throw new HttpException(500, 'Not Enough funds to draft selected players!');
                $session->getFlashBag()->add('error', 'Not Enough funds to draft selected players, Please check your entry and try again!');
            };

            $em = $this->getDoctrine()->getManager();
            $em->persist( $contestEntry );
            $em->flush();

            $this->addFlash(
                'success',
                'Contest Entry Updated!!'
            );

            return $this->redirect( $this->generateUrl( 'list_contestentries' ) );
        }

        return array(
            'contestEntry' => $contestEntry,
            'contestForm'  => $form->createView(),
            'contest'      => $contest,
            'playerList'   => $availablePlayers
        );
    }

Solution

  • you can add the callback validator on entity level:

    http://symfony.com/doc/current/reference/constraints/Callback.html