symfony2 self referencing entity has validation problems - validation

I have an entity that can have another entity of the same type as parent (self-referencing?).
So I have a container named Sweden, then another Container named Stockholm, and the $parent property of Stockholm is Sweden (these two are the same type of entity).
I have a validation constraint that makes sure no two entities can have the same name, but here arises a problem when I choose a parent for an entity, because the way the validations work seem to be that it then goes on to check not only the name of the entity Stockholm, but also goes to check the entire entity that I chose for parent, and obviously the name Stockholm is already in the DB (otherwise I couldn't have picked it for parent) there is a validation error, seems like a catch22 issue...
some code to illustrate... Any thoughts?
The entity
namespace BizTV\ContainerManagementBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use BizTV\ContainerManagementBundle\Validator\Constraints as BizTVAssert;
use BizTV\UserBundle\Entity\User as user;
use BizTV\ContainerManagementBundle\Entity\Container as Container;
/**
* BizTV\ContainerManagementBundle\Entity\Container
* #BizTVAssert\ContainerExists
* #ORM\Table(name="container")
* #ORM\Entity
*/
class Container
{
/**
* #var integer $id
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $name
* #Assert\NotBlank(message = "Du måste ange ett namn")
* #ORM\Column(name="name", type="string", length=255, nullable=true)
*/
private $name;
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* #var object BizTV\ContainerManagementBundle\Entity\ContainerType
*
* #ORM\ManyToOne(targetEntity="BizTV\ContainerManagementBundle\Entity\ContainerType")
* #ORM\JoinColumn(name="container_type", referencedColumnName="id", nullable=false)
*/
protected $containerType;
/**
* #var object BizTV\ContainerManagementBundle\Entity\ContainerSize
*
* #ORM\ManyToOne(targetEntity="BizTV\ContainerManagementBundle\Entity\ContainerSize")
* #ORM\JoinColumn(name="container_size", referencedColumnName="id", nullable=false)
*/
protected $containerSize;
/**
* #ORM\OneToMany(targetEntity="Container", mappedBy="parent")
*/
private $children;
/**
* #ORM\OneToMany(targetEntity="BizTV\ContentManagementBundle\Entity\Content", mappedBy="container")
* #ORM\OrderBy({"sortOrder" = "ASC"})
* above code does nothing, thought to use that instead of the current jQuery tinySort but aparently not...
*/
private $content;
/**
* #var object BizTV\ContainerManagementBundle\Entity\Container
*
* #ORM\ManyToOne(targetEntity="Container", inversedBy="children")
* #ORM\JoinColumn(name="parent", referencedColumnName="id", nullable=true)
*/
protected $parent;
/**
* #var object BizTV\LayoutManagementBundle\Entity\Layout
*
* #ORM\ManyToOne(targetEntity="BizTV\LayoutManagementBundle\Entity\Layout")
* #ORM\JoinColumn(name="screen_layout", referencedColumnName="id", nullable=true)
*/
protected $screen_layout;
/**
* #ORM\Column(type="boolean", nullable=true)
*
* This only applies to the monitor containerType, others will always have false here.
* The purpose of this bool is the option of never rendering this monitor with a layout (handy for ex. BrfTV servers with lower resolution)
*/
protected $prohibitLayout;
/**
* #ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="access")
*/
private $users;
public function __construct() {
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
$this->content = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set company
*
* #param BizTV\BackendBundle\Entity\company $company
*/
public function setCompany(\BizTV\BackendBundle\Entity\company $company)
{
$this->company = $company;
}
/**
* Get company
*
* #return BizTV\BackendBundle\Entity\company
*/
public function getCompany()
{
return $this->company;
}
/**
* Set containerType
*
* #param BizTV\ContainerManagementBundle\Entity\ContainerType $containerType
*/
public function setContainerType(\BizTV\ContainerManagementBundle\Entity\ContainerType $containerType)
{
$this->containerType = $containerType;
}
/**
* Get containerType
*
* #return BizTV\ContainerManagementBundle\Entity\ContainerType
*/
public function getContainerType()
{
return $this->containerType;
}
/**
* Set parent
*
* #param BizTV\ContainerManagementBundle\Entity\Container $parent
*/
public function setParent(\BizTV\ContainerManagementBundle\Entity\Container $parent = NULL)
{
$this->parent = $parent;
}
/**
* Get parent
*
* #return BizTV\ContainerManagementBundle\Entity\Container
*/
public function getParent()
{
return $this->parent;
}
/**
* Set screen_layout
*
* #param BizTV\LayoutManagementBundle\Entity\Layout $screenLayout
*/
public function setScreenLayout(\BizTV\LayoutManagementBundle\Entity\Layout $screenLayout = NULL)
{
$this->screen_layout = $screenLayout;
}
/**
* Get screen_layout
*
* #return BizTV\LayoutManagementBundle\Entity\Layout
*/
public function getScreenLayout()
{
return $this->screen_layout;
}
public function getSelectLabel()
{
if (isset($this->parent)) {
return $this->name . ' (' . $this->parent->getName() . ')';
}
else {
return $this->name;
}
}
/**
* Add users
*
* #param BizTV\UserBundle\Entity\User $users
*/
public function addUser(\BizTV\UserBundle\Entity\User $users)
{
$this->users[] = $users;
}
/**
* Get users
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
/**
* Add children
*
* #param BizTV\ContainerManagementBundle\Entity\Container $children
*/
public function addContainer(\BizTV\ContainerManagementBundle\Entity\Container $children)
{
$this->children[] = $children;
}
/**
* Get children
*
* #return Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
/**
* Add content
*
* #param BizTV\ContentManagementBundle\Entity\Content $content
*/
public function addContent(\BizTV\ContentManagementBundle\Entity\Content $content)
{
$this->content[] = $content;
}
/**
* Get content
*
* #return Doctrine\Common\Collections\Collection
*/
public function getContent()
{
return $this->content;
}
/**
* Set containerSize
*
* #param BizTV\ContainerManagementBundle\Entity\ContainerSize $containerSize
*/
public function setContainerSize(\BizTV\ContainerManagementBundle\Entity\ContainerSize $containerSize)
{
$this->containerSize = $containerSize;
}
/**
* Get containerSize
*
* #return BizTV\ContainerManagementBundle\Entity\ContainerSize
*/
public function getContainerSize()
{
return $this->containerSize;
}
/**
* Set prohibitLayout
*
* #param boolean $prohibitLayout
*/
public function setProhibitLayout($prohibitLayout)
{
$this->prohibitLayout = $prohibitLayout;
}
/**
* Get prohibitLayout
*
* #return boolean
*/
public function getProhibitLayout()
{
return $this->prohibitLayout;
}
}
Form
namespace BizTV\ContainerManagementBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Doctrine\ORM\EntityRepository;
class ContainerBuildingType extends AbstractType
{
function __construct(\BizTV\BackendBundle\Entity\company $company, \BizTV\ContainerManagementBundle\Entity\ContainerType $parentType) {
$this->parentType = $parentType;
$this->company = $company;
}
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name', 'text', array('label' => 'Namn på fastighet '));
$parentType = $this->parentType;
$company = $this->company;
$builder->add('parent', 'entity', array(
'label' => 'Välj ett geografiskt område för fastigheten ',
'class' => 'BizTVContainerManagementBundle:Container','property'=>'name',
'query_builder' => function(EntityRepository $er) use ($parentType, $company) {
return $er->createQueryBuilder('u')
->where('u.containerType = :type', 'u.company = :company')
->setParameters( array('type' => $parentType, 'company' => $company) )
->orderBy('u.name', 'ASC');
},
));
}
public function getName()
{
return 'biztv_containermanagementbundle_containerbuildingtype';
}
}
Constraint
use Symfony\Component\Validator\Constraint;
/**
* #Annotation
*/
class ContainerExists extends Constraint
{
public $message = 'Namnet är upptaget, vänligen välj ett annat.';
public function validatedBy()
{
return 'containerExists';
}
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
Validator
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Doctrine\ORM\EntityManager as EntityManager;
class ContainerExistsValidator extends ConstraintValidator
{
private $container;
private $em;
public function __construct(Container $container, EntityManager $em) {
$this->container = $container;
$this->em = $em;
}
public function isValid($object, Constraint $constraint)
{
$em = $this->em;
$container = $this->container;
$company = $this->container->get('security.context')->getToken()->getUser()->getCompany();
$parent = $object->getParent();
//Fetch entities with same name in the same container
$repository = $em->getRepository('BizTVContainerManagementBundle:Container');
$query = $repository->createQueryBuilder('c')
->where('c.company = :company and c.parent = :parent')
->setParameters(array('company' => $company, 'parent' => $parent))
->orderBy('c.name', 'ASC')
->getQuery();
$containers = $query->getResult();
foreach ($containers as $g) {
echo "testing ".$g->getName()." against ".$object->getName()."<br/>";
if ( $g->getName() == $object->getName() ) {
$this->setMessage('Namnet '.$object->getName().' är upptaget, vänligen välj ett annat');
return false;
}
}
return true;
}
}

I believe you have your relationships backwards;
Your parent should be OneToMany and your child should be ManyToOne
Unless you intended to have many parents only have 1 child and that child belong to many parents.

The answer to a similar question solved this issue as well:
symfony2 validation of child entity prevents editing of parent entity

Related

Custom operation denormalize entity relationships

My Entity(MealSet) has a file association so I have created a custom operation to process the request. My custom operation(MealSetController::class) attempts to denormalize the entity and the returns it. However, because my entity has a relationship, the denormalization fails and throws an error Nested documents for attribute \u0022mealSetIncludes\u0022 are not allowed. Use IRIs instead..
How would one denormalize an entity that has relationships from within a custom operation?
// MealSet entity
namespace App\Entity;
use App\Entity\MealAudienceCategory;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Controller\MealSetController;
use App\Repository\MealSetRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ApiResource(
* itemOperations={
* "get",
* "put"={
* "method"="POST",
* "path" = "/meal-sets/{id}",
* "controller" = MealSetController::class,
* "deserialize" = false
* },
* collectionOperations = {
* "get",
* "post" = {
* "security"="is_granted('CREATE_MENUAUDIENCE')",
* "method"="POST",
* "controller" = MealSetController::class,
* "deserialize" = false,
* }
* }
*)
* #ORM\Entity(repositoryClass=MealSetRepository::class)
* #UniqueEntity(
* fields={"name", "mealAudienceCategory"},
* message="The Meal Set name {{ value }} is already in use."
*)
* #Vich\Uploadable
*/
class MealSet
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=45)
* #Groups({
* "mealset:read",
* "mealset:write",
* "mealaudiencecategory:read",
*})
* #Assert\NotBlank
* #Assert\Length(
* min = 2,
* max = 45,
* minMessage = "Name must be at least {{ limit }} characters long",
* maxMessage = "Name cannot be longer than {{ limit }} characters",
* )
*/
private $name;
/**
* #ORM\Column(type="string", length=255)
* #Groups({
* "mealset:read",
* "mealset:write",
* "mealaudiencecategory:read",
*})
* #Assert\NotBlank
* #Assert\Length(
* min = 2,
* max = 255,
* minMessage = "Description must be at least {{ limit }} characters long",
* maxMessage = "Description cannot be longer than {{ limit }} characters",
* )
*/
private $description;
/**
* #ORM\Column(type="boolean")
* #Groups({
* "mealset:read",
* "mealset:write",
* "mealaudiencecategory:read",
*})
* #Assert\Type(
* type="boolean",
* message="The value {{ value }} is not a valid {{ type }}."
* )
*/
private $published;
/**
* #ORM\Column(type="integer")
* #Groups({
* "mealset:read",
* "mealset:write"
*})
* #Assert\Type(
* type="integer",
* message="The value {{ value }} is not a valid {{ type }}."
* )
*/
private $displayOrder;
/**
* #var MealAudienceCategory
* #ORM\ManyToOne(targetEntity=MealAudienceCategory::class, inversedBy="mealSets")
* #ORM\JoinColumn(nullable=false)
* #Groups({
* "mealset:read",
* "mealset:write"
*})
*/
private $mealAudienceCategory;
/**
* #ORM\OneToMany(targetEntity=MealSetIncludes::class, mappedBy="mealSet", cascade={"persist", "remove"}, orphanRemoval=true)
* #Groups({
* "mealset:read",
* "mealset:write"
*})
*/
private $mealSetIncludes;
/**
* #ORM\OneToMany(targetEntity=MealSetGroup::class, mappedBy="mealSet", orphanRemoval=true)
* #Groups({
* "mealset:read",
* "mealset:write"
*})
*/
private $mealSetGroups;
/**
* #Groups({
* "menuaudience:read",
*})
*/
public $contentUrl;
/**
* #Vich\UploadableField(mapping="media_object", fileNameProperty="filePath")
* #Groups({
* "menuaudience:write",
*})
*/
public $file = null;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $filePath;
/**
* #ORM\Column(type="datetime_immutable")
*/
private $updatedAt;
public function __construct()
{
$this->mealSetSection = new ArrayCollection();
$this->mealSetIncludes = new ArrayCollection();
$this->mealSetGroups = new ArrayCollection();
$this->setUpdatedAt(new \DateTimeImmutable());
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getPublished(): ?bool
{
return $this->published;
}
public function setPublished(bool $published): self
{
$this->published = $published;
return $this;
}
public function getDisplayOrder(): ?int
{
return $this->displayOrder;
}
public function setDisplayOrder(int $displayOrder): self
{
$this->displayOrder = $displayOrder;
return $this;
}
public function getMealAudienceCategory(): ?MealAudienceCategory
{
return $this->mealAudienceCategory;
}
public function setMealAudienceCategory(?MealAudienceCategory $mealAudienceCategory): self
{
$this->mealAudienceCategory = $mealAudienceCategory;
return $this;
}
/**
* #return Collection|MealSetIncludes[]
* #Assert\Valid()
*/
public function getMealSetIncludes(): Collection
{
return $this->mealSetIncludes;
}
public function addMealSetInclude(MealSetIncludes $mealSetInclude): self
{
if (!$this->mealSetIncludes->contains($mealSetInclude)) {
$this->mealSetIncludes[] = $mealSetInclude;
$mealSetInclude->setMealSet($this);
}
return $this;
}
public function removeMealSetInclude(MealSetIncludes $mealSetInclude): self
{
if ($this->mealSetIncludes->contains($mealSetInclude)) {
$this->mealSetIncludes->removeElement($mealSetInclude);
// set the owning side to null (unless already changed)
if ($mealSetInclude->getMealSet() === $this) {
$mealSetInclude->setMealSet(null);
}
}
return $this;
}
/**
* #return Collection|MealSetGroup[]
*/
public function getMealSetGroups(): Collection
{
return $this->mealSetGroups;
}
public function addMealSetGroup(MealSetGroup $mealSetGroup): self
{
if (!$this->mealSetGroups->contains($mealSetGroup)) {
$this->mealSetGroups[] = $mealSetGroup;
$mealSetGroup->setMealSet($this);
}
return $this;
}
public function removeMealSetGroup(MealSetGroup $mealSetGroup): self
{
if ($this->mealSetGroups->removeElement($mealSetGroup)) {
// set the owning side to null (unless already changed)
if ($mealSetGroup->getMealSet() === $this) {
$mealSetGroup->setMealSet(null);
}
}
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeImmutable $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getFilePath(): ?string
{
return $this->filePath;
}
public function getContentUrl(): ?string {
return $this->contentUrl;
}
public function setFilePath($filePath): self
{
$this->filePath = $filePath;
return $this;
}
}
class MealSetController extends AbstractController
{
public function __invoke($slug = '', RequestStack $requestStack, MealSetRepository $em): MealSet
{
/*
Determine if they are trying to edit an entity or create an entity.
If edit, find the entity and use that object.
*/
if($slug) {
$obj = $em->findOneBySlug($slug);
if(!$obj)
throw new BadRequestHttpException('Cannot find MealSet where SLUG ='.$slug);
} else {
$obj = new MealSet();
}
$serializer = $this->get("serializer");
$request = $requestStack->getCurrentRequest();
$data = array_filter($request->request->all(), function($x) { return ($x) ? true : false; }); //Grab the post data and filter out any empty strings.
$extractors = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
(new ObjectNormalizer(null, null, null, $extractors))->denormalize($data, MenuAudience::class, 'json', [
AbstractNormalizer::OBJECT_TO_POPULATE => $obj,
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT => true
]);
$uploadedFile = $request->files->get('file');
if($uploadedFile)
$obj->setFile($uploadedFile);
return $obj;
}
}

Pusher\\ApiErrorException(code: 0) error in Chat system

After Message save broadcasting occurs this issue:
local.ERROR: {"userId":3,"exception":"[object] (Pusher\ApiErrorException(code: 0): at C:\xampp\htdocs\fm\script\vendor\pusher\pusher-php-server\src\Pusher.php:533)
[stacktrace]
#0 C:\xampp\htdocs\fm\script\vendor
nahid\talk\src\Live\Webcast.php(51): Pusher\Pusher->trigger(Array, 'talk-send-messa...', Array)
nahid\talk\src\Live\Broadcast.php(85): Nahid\Talk\Live\Broadcast->dispatch(Object(Nahid\Talk\Live\Webcast))
#22 C:\xampp\htdocs\fm\script\vendor
nahid\talk\src\Talk.php(106): Nahid\Talk\Live\Broadcast->transmission(Object(Nahid\Talk\Messages\Message))
#23 C:\xampp\htdocs\fm\script\vendor
nahid\talk\src\Talk.php(268): Nahid\Talk\Talk->makeMessage(2, Object(Nahid\Talk\Messages\Message))
Pages:
Webcast.php
class Webcast implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
/*
* Message Model Instance
*
* #var object
* */
protected $message;
/*
* Broadcast class instance
*
* #var object
* */
protected $broadcast;
/**
* Set message collections to the properties.
*/
public function __construct($message)
{
$this->message = $message;
}
/*
* Execute the job and broadcast to the pusher channels
*
* #param \Nahid\Talk\Live\Broadcast $broadcast
* #return void
*/
public function handle(Broadcast $broadcast)
{
$this->broadcast = $broadcast;
$senderIdKey = $this->broadcast->getConfig('user.ownerKey') ? $this->broadcast->getConfig('user.ownerKey') : 'id';
$toUser = ($this->message['sender'][ $senderIdKey] == $this->message['conversation']['user_one']) ? $this->message['conversation']['user_two'] : $this->message['conversation']['user_one'];
$channelForUser = $this->broadcast->getConfig('broadcast.app_name').'-user-'.$toUser;
$channelForConversation = $this->broadcast->getConfig('broadcast.app_name').'-conversation-'.$this->message['conversation_id'];
// try {
$this->broadcast->pusher->trigger([sha1($channelForUser), sha1($channelForConversation)], 'talk-send-message', $this->message);
// } catch (ApiErrorException $e) {
// throw new BroadcastException(
// sprintf('Pusher error: %s.', $e->getMessage())
// );
// }
}
}
Broadcast.php
class Broadcast
{
use DispatchesJobs;
/*
* Constant for talk config prefix
*
* #const string
* */
const CONFIG_PATH = 'talk';
/*
* Set all configs from talk configurations
*
* #var array
* */
protected $config;
/*
* Pusher instance
*
* #var object
* */
public $pusher;
/**
* Connect pusher and get all credentials from config.
*
* #param \Illuminate\Contracts\Config\Repository $config
*/
public function __construct(Repository $config)
{
$this->config = $config;
$this->pusher = $this->connectPusher();
}
/**
* Make pusher connection.
*
* #param array $options
*
* #return object | bool
*/
protected function connectPusher($options = [])
{
if ($this->getConfig('broadcast.enable')) {
$appId = $this->getConfig('broadcast.pusher.app_id');
$appKey = $this->getConfig('broadcast.pusher.app_key');
$appSecret = $this->getConfig('broadcast.pusher.app_secret');
$appOptions = $this->getConfig('broadcast.pusher.options');
$newOptions = array_merge($appOptions, $options);
$pusher = new Pusher($appKey, $appSecret, $appId, $newOptions);
return $pusher;
}
return false;
}
/**
* Dispatch the job to the queue.
*
* #param \Nahid\Talk\Messages\Message $message
*/
public function transmission(Message $message)
{
if (!$this->pusher) {
return false;
}
$sender = $message->sender->toArray();
$messageArray = $message->toArray();
$messageArray['sender'] = $sender;
$this->dispatch(new Webcast($messageArray));
}
/**
* get specific config from talk configurations.
*
* #param string
*
* #return string|array|int
*/
public function getConfig($name)
{
return $this->config->get(self::CONFIG_PATH.'.'.$name);
}
}

Joins with Laravel Eloquent

I'm learning a bit of Laravel coming over from Symfony, and i'm a little confused with how joins work with eloquent. so that i have have the returned object as my model class rather than a stdClass.
Currently i am doing this:
$query = DB::table('caravan')
->join('type','caravan.type_id', '=', 'type.id')
->join('category','caravan.category_id', '=', 'category.id')
->where('type.name','=', 'New')
->where('category.name', '=', ucwords(strtolower($category)))
->orderBy($orderBy,$order);
This works, it brings through all the correct records with the joined columns, but i don't want it to be a stdClass.
My caravan model looks like this:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
/**
* Class Caravan
* #package App\Models
* #property int $stock
* #property int $branch_id
* #property int $category_id
* #property int $type_id
* #property string $reg
* #property string $make
* #property string $model
* #property string $specification
* #property string $derivative
* #property string $engine_size
* #property string $engine_type
* #property string $transmission
* #property string $colour
* #property int $year
* #property int $mileage
* #property boolean $commercial
* #property double $sales_siv
* #property double $retail
* #property double $web_price
* #property string $sub_heading;
* #property string $advertising_notes
* #property string $manager_comments
* #property double $previous_price
* #property double $guide_retail_price
* #property boolean $available_for_sale
* #property boolean $advertised_on_own_website
* #property int $berths
* #property int $axles
* #property string $layout_type
* #property double $width
* #property double $length
* #property double $height
* #property int $kimberley_unit_id
* #property \DateTime $kimberley_date_updated
*
*/
class Caravan extends Model
{
use HasFactory;
/**
* #var string
*/
public $table = 'caravan';
/**
* #var string[]
*/
protected $casts = [
'kimberley_date_updated' => 'datetime:Y-m-d H:i:s',
'created_at' => 'datetime:Y-m-d H:i:s',
'updated_at' => 'datetime:Y-m-d H:i:s',
'web_price' => 'decimal: 2',
'previous_price' => 'decimal: 2'
];
/**
* #return HasOne
*/
public function category() : HasOne
{
return $this->hasOne(Category::class, 'id', 'category_id');
}
/**
* #return HasOne
*/
public function type() : HasOne
{
die("DD");
return $this->hasOne(Type::class, 'id', 'type_id');
}
/**
* #return int
*/
public function getStock(): int
{
return $this->stock;
}
/**
* #param int $stock
* #return $this
*/
public function setStock(int $stock): self
{
$this->stock = $stock;
return $this;
}
/**
* #return int
*/
public function getBranchId(): int
{
return $this->branch_id;
}
/**
* #param int $branch_id
* #return $this
*/
public function setBranchId(int $branch_id): self
{
$this->branch_id = $branch_id;
return $this;
}
/**
* #param Branch $branch
* #return $this
*/
public function setBranch(Branch $branch) : self
{
$this->branch_id = $branch->id;
return $this;
}
/**
* #return int
*/
public function getCategoryId(): int
{
return $this->category_id;
}
/**
* #param int $category_id
* #return $this
*/
public function setCategoryId(int $category_id): self
{
$this->category_id = $category_id;
return $this;
}
/**
* #param Category $cat
* #return $this
*/
public function setCategory(Category $cat) : self
{
$this->category_id = $cat->id;
return $this;
}
/**
* #return int
*/
public function getTypeId(): int
{
return $this->type_id;
}
/**
* #param int $type_id
* #return $this
*/
public function setTypeId(int $type_id): self
{
$this->type_id = $type_id;
return $this;
}
/**
* #param Type $type
* #return $this
*/
public function setType(Type $type) : self
{
$this->type_id = $type->id;
return $this;
}
/**
* #return string
*/
public function getReg(): string
{
return $this->reg;
}
/**
* #param string $reg
* #return $this
*/
public function setReg(string $reg): self
{
$this->reg = $reg;
return $this;
}
/**
* #return string
*/
public function getMake(): string
{
return $this->make;
}
/**
* #param string $make
* #return $this
*/
public function setMake(string $make): self
{
$this->make = $make;
return $this;
}
/**
* #return string
*/
public function getModel(): string
{
return $this->model;
}
/**
* #param string $model
* #return $this
*/
public function setModel(string $model): self
{
$this->model = $model;
return $this;
}
/**
* #return string
*/
public function getSpecification(): string
{
return $this->specification;
}
/**
* #param string $specification
* #return $this
*/
public function setSpecification(string $specification): self
{
$this->specification = $specification;
return $this;
}
/**
* #return string
*/
public function getDerivative(): string
{
return $this->derivative;
}
/**
* #param string $derivative
* #return $this
*/
public function setDerivative(string $derivative): self
{
$this->derivative = $derivative;
return $this;
}
/**
* #return string
*/
public function getEngineSize(): string
{
return $this->engine_size;
}
/**
* #param string $engine_size
* #return $this
*/
public function setEngineSize(string $engine_size): self
{
$this->engine_size = $engine_size;
return $this;
}
/**
* #return string
*/
public function getEngineType(): string
{
return $this->engine_type;
}
/**
* #param string $engine_type
* #return $this
*/
public function setEngineType(string $engine_type): self
{
$this->engine_type = $engine_type;
return $this;
}
/**
* #return string
*/
public function getTransmission(): string
{
return $this->transmission;
}
/**
* #param string $transmission
* #return $this
*/
public function setTransmission(string $transmission): self
{
$this->transmission = $transmission;
return $this;
}
/**
* #return string
*/
public function getColour(): string
{
return $this->colour;
}
/**
* #param string $colour
* #return $this
*/
public function setColour(string $colour): self
{
$this->colour = $colour;
return $this;
}
/**
* #return int
*/
public function getYear(): int
{
return $this->year;
}
/**
* #param int $year
* #return $this
*/
public function setYear(int $year): self
{
$this->year = $year;
return $this;
}
/**
* #return int
*/
public function getMileage(): int
{
return $this->mileage;
}
/**
* #param int $mileage
* #return $this
*/
public function setMileage(int $mileage): self
{
$this->mileage = $mileage;
return $this;
}
/**
* #return bool
*/
public function isCommercial(): bool
{
return (bool)$this->commercial;
}
/**
* #param bool $commercial
* #return $this
*/
public function setCommercial(bool $commercial): self
{
$this->commercial = (int)$commercial;
return $this;
}
/**
* #return float
*/
public function getSalesSiv(): float
{
return $this->sales_siv;
}
/**
* #param float|int $sales_siv
* #return $this
*/
public function setSalesSiv(float $sales_siv = 0): self
{
$this->sales_siv = $sales_siv;
return $this;
}
/**
* #return float
*/
public function getRetail(): float
{
return $this->retail;
}
/**
* #param float|int $retail
* #return $this
*/
public function setRetail(float $retail = 0): self
{
$this->retail = $retail;
return $this;
}
/**
* #return float
*/
public function getWebPrice(): float
{
return $this->web_price;
}
/**
* #param float|int $web_price
* #return $this
*/
public function setWebPrice(float $web_price = 0): self
{
$this->web_price = $web_price;
return $this;
}
/**
* #return string
*/
public function getSubHeading(): string
{
return $this->sub_heading;
}
/**
* #param string $sub_heading
* #return $this
*/
public function setSubHeading(string $sub_heading): self
{
$this->sub_heading = $sub_heading;
return $this;
}
/**
* #return string
*/
public function getAdvertisingNotes(): string
{
return $this->advertising_notes;
}
/**
* #param string $advertising_notes
* #return $this
*/
public function setAdvertisingNotes(string $advertising_notes): self
{
$this->advertising_notes = $advertising_notes;
return $this;
}
/**
* #return string
*/
public function getManagerComments(): string
{
return $this->manager_comments;
}
/**
* #param string $managerComments
* #return $this
*/
public function setManagerComments(string $managerComments): self
{
$this->manager_comments = $managerComments;
return $this;
}
/**
* #return float
*/
public function getPreviousPrice(): float
{
return $this->previous_price;
}
/**
* #param float $previous_price
* #return $this
*/
public function setPreviousPrice(float $previous_price): self
{
$this->previous_price = $previous_price;
return $this;
}
/**
* #return float
*/
public function getGuideRetailPrice(): float
{
return $this->guide_retail_price;
}
/**
* #param float $guide_retail_price
* #return $this
*/
public function setGuideRetailPrice(float $guide_retail_price): self
{
$this->guide_retail_price = $guide_retail_price;
return $this;
}
/**
* #return bool
*/
public function isAvailableForSale(): bool
{
return $this->available_for_sale;
}
/**
* #param bool $available_for_sale
* #return $this
*/
public function setAvailableForSale(bool $available_for_sale): self
{
$this->available_for_sale = (int)$available_for_sale;
return $this;
}
/**
* #return bool
*/
public function isAdvertisedOnOwnWebsite(): bool
{
return $this->advertised_on_own_website;
}
/**
* #param bool $advertised_on_own_website
* #return $this
*/
public function setAdvertisedOnOwnWebsite(bool $advertised_on_own_website): self
{
$this->advertised_on_own_website = (int)$advertised_on_own_website;
return $this;
}
/**
* #return int
*/
public function getBerths(): int
{
return $this->berths;
}
/**
* #param int $berth
*/
public function setBerths(int $berths): self
{
$this->berths = $berths;
return $this;
}
/**
* #return int
*/
public function getAxles(): int
{
return $this->axles;
}
/**
* #param int $axles
* #return $this
*/
public function setAxles(int $axles): self
{
$this->axles = $axles;
return $this;
}
/**
* #return string
*/
public function getLayoutType(): string
{
return $this->layout_type;
}
/**
* #param string $layout_type
* #return $this
*/
public function setLayoutType(string $layout_type): self
{
$this->layout_type = $layout_type;
return $this;
}
/**
* #return float
*/
public function getWidth(): float
{
return $this->width;
}
/**
* #param float $width
* #return $this
*/
public function setWidth(float $width): self
{
$this->width = $width;
return $this;
}
/**
* #return float
*/
public function getLength(): float
{
return $this->length;
}
/**
* #param float $length
* #return $this
*/
public function setLength(float $length): self
{
$this->length = $length;
return $this;
}
/**
* #return float
*/
public function getHeight(): float
{
return $this->height;
}
/**
* #param float $height
* #return $this
*/
public function setHeight(float $height): self
{
$this->height = $height;
return $this;
}
/**
* #return int
*/
public function getKimberleyUnitId(): int
{
return $this->kimberley_unit_id;
}
/**
* #param int $kimberley_unit_id
* #return $this
*/
public function setKimberleyUnitId(int $kimberley_unit_id): self
{
$this->kimberley_unit_id = $kimberley_unit_id;
return $this;
}
/**
* #return \DateTime
*/
public function getKimberleyDateUpdated(): \DateTime
{
return $this->kimberley_date_updated;
}
/**
* #param \DateTime $kimberley_date_updated
* #return $this
*/
public function setKimberleyDateUpdated(\DateTime $kimberley_date_updated): self
{
$this->kimberley_date_updated = $kimberley_date_updated;
return $this;
}
}
So i have the HasOne parts at the top to be able to use the model to get the type and category, but how would i do this to replace my query above with the where clause?
I have tried something like:
Caravan::with(['type','category'])->where('type.name','New');
This doesn't work, just says type doesn't exist in so many words.
So what i want to get back, is the model like i would just running say Caravan::all() which i would then be able to loop and use something like $caravan->type->name
EDIT
Answer below from Wahyu:
Caravan::with(['type' => function ($query) {
$query->where('name', 'New');
}, 'category' => function($query) use ($category) {
$query->where('name',ucwords(strtolower($category)));
}])->orderBy($orderBy,$order);
This query runs fine however, it's bringing results back where type is Used as well as New so the query isn't working.
Also, looping the results, i still can't use the HasOne method in my model to do $caravan->type->name
However, Caravan::all() as a test allows me to use $caravan->type->name in the loop and that works ok, so the where query is still an issue
You can accomplish by passing an array of relationships to the with method where the array key is a relationship name and the array value is a closure that adds additional constraints to the eager loading query:
Caravan::with(['type' => function ($query) {
$query->where('name', 'New');
}, 'category'])->get();
Update (different question):
i still can't use the HasOne method in my model to do $caravan->type->name
public function type() : HasOne
{
return $this->hasOne(Type::class, 'id', 'type_id');
}
So, you can access the Type model from Caravan model. You can define the inverse of a hasOne relationship using the belongsTo method:
public function type()
{
return $this->belongsTo(Type::class);
}
When invoking the type method, Eloquent will attempt to find a Type model that has an id which matches the type_id column on the Caravan model.
If you are using a recent version of Laravel you can do something like:
Caravan::query()
->whereRelation('type', 'name', 'New')
->whereRelation('category', 'name', ucwords(strtolower($category)))
->orderBy($orderBy, $order)
->get();
Otherwise, you can use the eloquent whereHas() method to achieve the same result.
Caravan::query()
->whereHas('type', fn (Builder $query) => $query->where('name', 'New'))
->whereHas('category', fn (Builder $query) => $query->where('name', ucwords(strtolower($category))))
->orderBy($orderBy, $order)
->get();
Looking at your model relations I think your relations should be one to many instead of one to one. If so your relations should be:
public function type()
{
return $this->belongsTo(Type::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}

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
);
}
you can add the callback validator on entity level:
http://symfony.com/doc/current/reference/constraints/Callback.html

Symfony Doctrine One to Many Validation

I'm wanting to validate all the images that are linked to the entity by one to many relationship with the KitchenImage table.
Here's my controller function:
public function addAction(Request $request)
{
// Check for POST
if ($request->getMethod() == 'POST') {
// Load Doctrine
$em = $this->getDoctrine()->getManager();
// Set Validator
$validator = $this->get('validator');
// Kitchen Details
$kitchen = new Kitchen();
$kitchen->setName($request->request->get('name'));
$kitchen->setDescription($request->request->get('description'));
$kitchen->setImage($request->files->get('main-image'));
// Sub Images
foreach ($request->files->get('sub-images') as $subimage)
{
$image = new KitchenImage();
$image->setImage($subimage);
$image->setKitchen($kitchen);
$image->upload();
$em->persist($image);
$kitchen->addImage($image);
}
// Validation
$errors = $validator->validate($kitchen);
if (count($errors) > 0) {
return new Response(print_r($errors, true));
}
else {
$kitchen->upload();
$em->persist($kitchen);
$em->flush();
return new Response('The kitchen is valid! Yes!');
}
}
return $this->render('PWDAdminBundle:Pages:add-kitchen.html.twig');
}
Kitchen Entity (Removed setters and getters for formatting):
/**
* #ORM\Entity
* #ORM\Table(name="kitchen")
*/
class Kitchen
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
* #Assert\NotBlank()
*/
protected $name;
/**
* #ORM\Column(type="text")
* #Assert\NotBlank()
*/
protected $description;
/**
* #Assert\File(maxSize="6000000")
* #Assert\NotNull()
* #Assert\Image(
* minWidth = 800,
* maxWidth = 800,
* minHeight = 467,
* maxHeight = 467
* )
*/
protected $image;
/**
* #ORM\OneToMany(targetEntity="KitchenImage", mappedBy="kitchen")
*/
protected $images;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $imagePath;
public function __construct()
{
$this->images = new ArrayCollection();
}
KitchenImage Entity:
class KitchenImage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #Assert\File(maxSize="6000000")
* #Assert\NotNull()
* #Assert\Image(
* minWidth = 800,
* maxWidth = 800,
* minHeight = 467,
* maxHeight = 467
* )
*/
protected $image;
/**
* #ORM\ManyToOne(targetEntity="Kitchen", inversedBy="image")
* #ORM\JoinColumn(name="kitchen_id", referencedColumnName="id")
*/
protected $kitchen;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
I have tried the following on the Kitchen Entity:
/**
* #ORM\OneToMany(targetEntity="KitchenImage", mappedBy="kitchen")
* #Assert\All({
* #Assert\Valid
* })
*/
protected $images;
But I get the error message:
"The constraint Valid cannot be nested inside constraint Symfony\Component\Validator\Constraints\All.

Resources