Custom operation denormalize entity relationships - api-platform.com

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;
}
}

Related

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);
}

community/HelloWired_Free_Theme_1_4: Unknown SSL protocol error in connection to connect20.magentocommerce.com:443

I don't try to install some themes and other extensions on magento 1.9 on my mec.
The error is:
community/HelloWired_Free_Theme_1_4: Unknown SSL protocol error in
connection to connect20.magentocommerce.com:443
Can you help me, please?
Thanks!
Try to use this code in downloader/lib/Mage/HTTP/Client/Curl.php
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* #category Mage
* #package Mage_HTTP
* #copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Class to work with HTTP protocol using curl library
*
* #category Mage
* #package Mage_Connect
* #author Magento Core Team <core#magentocommerce.com>
*/
class Mage_HTTP_Client_Curl implements Mage_HTTP_IClient
{
/**
* Session Cookie storage, magento_root/var directory used
* #var string
*/
const COOKIE_FILE = 'var/cookie';
/**
* Hostname
* #var string
*/
protected $_host = 'localhost';
/**
* Port
* #var int
*/
protected $_port = 80;
/**
* Stream resource
* #var object
*/
protected $_sock = null;
/**
* Request headers
* #var array
*/
protected $_headers = array();
/**
* Fields for POST method - hash
* #var array
*/
protected $_postFields = array();
/**
* Request cookies
* #var array
*/
protected $_cookies = array();
/**
* Response headers
* #var array
*/
protected $_responseHeaders = array();
/**
* Response body
* #var string
*/
protected $_responseBody = '';
/**
* Response status
* #var int
*/
protected $_responseStatus = 0;
/**
* Request timeout
* #var intunknown_type
*/
protected $_timeout = 300;
/**
* TODO
* #var int
*/
protected $_redirectCount = 0;
/**
* Curl
* #var object
*/
protected $_ch;
/**
* User ovverides options hash
* Are applied before curl_exec
*
* #var array();
*/
protected $_curlUserOptions = array();
/**
* User credentials
*
* #var array();
*/
protected $_auth = array();
/**
* Set request timeout, msec
*
* #param int $value
*/
public function setTimeout($value)
{
$this->_timeout = (int) $value;
}
/**
* Constructor
*/
public function __construct()
{
}
/**
* Destructor
* Removes temporary environment
*/
public function __destruct()
{
if (is_file(self::COOKIE_FILE)) {
#unlink(self::COOKIE_FILE);
}
}
/**
* Set headers from hash
* #param array $headers
*/
public function setHeaders($headers)
{
$this->_headers = $headers;
}
/**
* Add header
*
* #param $name name, ex. "Location"
* #param $value value ex. "http://google.com"
*/
public function addHeader($name, $value)
{
$this->_headers[$name] = $value;
}
/**
* Remove specified header
*
* #param string $name
*/
public function removeHeader($name)
{
unset($this->_headers[$name]);
}
/**
* Authorization: Basic header
* Login credentials support
*
* #param string $login username
* #param string $pass password
*/
public function setCredentials($login, $pass)
{
$this->_auth['login'] = $login;
$this->_auth['password'] = $pass;
//$val= base64_encode( "$login:$pass" );
//$this->addHeader( "Authorization", "Basic $val" );
}
/**
* Add cookie
*
* #param string $name
* #param string $value
*/
public function addCookie($name, $value)
{
$this->_cookies[$name] = $value;
}
/**
* Remove cookie
*
* #param string $name
*/
public function removeCookie($name)
{
unset($this->_cookies[$name]);
}
/**
* Set cookies array
*
* #param array $cookies
*/
public function setCookies($cookies)
{
$this->_cookies = $cookies;
}
/**
* Clear cookies
*/
public function removeCookies()
{
$this->setCookies(array());
}
/**
* Make GET request
*
* #param string $uri uri relative to host, ex. "/index.php"
*/
public function get($uri)
{
$this->makeRequest("GET", $uri);
}
/**
* Make POST request
* #see lib/Mage/HTTP/Mage_HTTP_Client#post($uri, $params)
*/
public function post($uri, $params)
{
$this->makeRequest("POST", $uri, $params);
}
/**
* Get response headers
*
* #return array
*/
public function getHeaders()
{
return $this->_responseHeaders;
}
/**
* Get response body
*
* #return string
*/
public function getBody()
{
return $this->_responseBody;
}
/**
* Get cookies response hash
*
* #return array
*/
public function getCookies()
{
if(empty($this->_responseHeaders['Set-Cookie'])) {
return array();
}
$out = array();
foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
$values = explode("; ", $row);
$c = count($values);
if(!$c) {
continue;
}
list($key, $val) = explode("=", $values[0]);
if(is_null($val)) {
continue;
}
$out[trim($key)] = trim($val);
}
return $out;
}
/**
* Get cookies array with details
* (domain, expire time etc)
* #return array
*/
public function getCookiesFull()
{
if(empty($this->_responseHeaders['Set-Cookie'])) {
return array();
}
$out = array();
foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
$values = explode("; ", $row);
$c = count($values);
if(!$c) {
continue;
}
list($key, $val) = explode("=", $values[0]);
if(is_null($val)) {
continue;
}
$out[trim($key)] = array('value'=>trim($val));
array_shift($values);
$c--;
if(!$c) {
continue;
}
for($i = 0; $i<$c; $i++) {
list($subkey, $val) = explode("=", $values[$i]);
$out[trim($key)][trim($subkey)] = trim($val);
}
}
return $out;
}
/**
* Get response status code
* #see lib/Mage/HTTP/Mage_HTTP_Client#getStatus()
*/
public function getStatus()
{
return $this->_responseStatus;
}
/**
* Make request
* #param string $method
* #param string $uri
* #param array $params
* #return null
*/
protected function makeRequest($method, $uri, $params = array())
{
static $isAuthorizationRequired = 0;
$this->_ch = curl_init();
// make request via secured layer
if ($isAuthorizationRequired && strpos($uri, 'https://') !== 0) {
$uri = str_replace('http://', '', $uri);
$uri = 'https://' . $uri;
}
$this->curlOption(CURLOPT_URL, $uri);
$this->curlOption(CURLOPT_SSL_VERIFYPEER, FALSE);
$this->curlOption(CURLOPT_SSL_VERIFYHOST, 2);
// force method to POST if secured
if ($isAuthorizationRequired) {
$method = 'POST';
}
if($method == 'POST') {
$this->curlOption(CURLOPT_POST, 1);
$postFields = is_array($params) ? $params : array();
if ($isAuthorizationRequired) {
$this->curlOption(CURLOPT_COOKIEJAR, self::COOKIE_FILE);
$this->curlOption(CURLOPT_COOKIEFILE, self::COOKIE_FILE);
$postFields = array_merge($postFields, $this->_auth);
}
if (!empty($postFields)) {
$this->curlOption(CURLOPT_POSTFIELDS, $postFields);
}
} elseif($method == "GET") {
$this->curlOption(CURLOPT_HTTPGET, 1);
} else {
$this->curlOption(CURLOPT_CUSTOMREQUEST, $method);
}
if(count($this->_headers)) {
$heads = array();
foreach($this->_headers as $k=>$v) {
$heads[] = $k.': '.$v;
}
$this->curlOption(CURLOPT_HTTPHEADER, $heads);
}
if(count($this->_cookies)) {
$cookies = array();
foreach($this->_cookies as $k=>$v) {
$cookies[] = "$k=$v";
}
$this->curlOption(CURLOPT_COOKIE, implode(";", $cookies));
}
if($this->_timeout) {
$this->curlOption(CURLOPT_TIMEOUT, $this->_timeout);
}
if($this->_port != 80) {
$this->curlOption(CURLOPT_PORT, $this->_port);
}
$this->curlOption(CURLOPT_RETURNTRANSFER, 1);
$this->curlOption(CURLOPT_FOLLOWLOCATION, 1);
$this->curlOption(CURLOPT_HEADERFUNCTION, array($this,'parseHeaders'));
if(count($this->_curlUserOptions)) {
foreach($this->_curlUserOptions as $k=>$v) {
$this->curlOption($k, $v);
}
}
$this->_responseHeaders = array();
$this->_responseBody = curl_exec($this->_ch);
$err = curl_errno($this->_ch);
if($err) {
$this->doError(curl_error($this->_ch));
}
if(!$this->getStatus()) {
return $this->doError("Invalid response headers returned from server.");
}
curl_close($this->_ch);
if (403 == $this->getStatus()) {
if (!$isAuthorizationRequired) {
$isAuthorizationRequired++;
$this->makeRequest($method, $uri, $params);
$isAuthorizationRequired=0;
} else {
return $this->doError(sprintf('Access denied for %s#%s', $_SESSION['auth']['login'], $uri));
}
}
}
/**
* Throw error excpetion
* #param $string
* #throws Exception
*/
public function isAuthorizationRequired()
{
if (isset($_SESSION['auth']['username']) && isset($_SESSION['auth']['password']) && !empty($_SESSION['auth']['username'])) {
return true;
}
return false;
}
/**
* Throw error excpetion
* #param $string
* #throws Exception
*/
public function doError($string)
{
throw new Exception($string);
}
/**
* Parse headers - CURL callback functin
*
* #param resource $ch curl handle, not needed
* #param string $data
* #return int
*/
protected function parseHeaders($ch, $data)
{
if(preg_match('/^HTTP\/[\d\.x]+ (\d+)/', $data, $m)) {
if (isset($m[1])) {
$this->_responseStatus = (int)$m[1];
}
} else {
$name = $value = '';
$out = explode(": ", trim($data), 2);
if(count($out) == 2) {
$name = $out[0];
$value = $out[1];
}
if(strlen($name)) {
if("Set-Cookie" == $name) {
if(!isset($this->_responseHeaders[$name])) {
$this->_responseHeaders[$name] = array();
}
$this->_responseHeaders[$name][] = $value;
} else {
$this->_responseHeaders[$name] = $value;
}
}
}
return strlen($data);
}
/**
* Set curl option directly
*
* #param string $name
* #param string $value
*/
protected function curlOption($name, $value)
{
curl_setopt($this->_ch, $name, $value);
}
/**
* Set curl options array directly
* #param array $array
*/
protected function curlOptions($array)
{
curl_setopt_array($this->_ch, $arr);
}
/**
* Set CURL options ovverides array *
*/
public function setOptions($arr)
{
$this->_curlUserOptions = $arr;
}
/**
* Set curl option
*/
public function setOption($name, $value)
{
$this->_curlUserOptions[$name] = $value;
}
}

Magento Plugin installation gives Error as : Unknown SSL protocol error in connection

Magento Plugin installation Error : Unknown SSL protocol error when trying to install magento plugin from magento connect.
Try to use this code in downloader/lib/Mage/HTTP/Client/Curl.php
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* #category Mage
* #package Mage_HTTP
* #copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Class to work with HTTP protocol using curl library
*
* #category Mage
* #package Mage_Connect
* #author Magento Core Team <core#magentocommerce.com>
*/
class Mage_HTTP_Client_Curl
implements Mage_HTTP_IClient
{
/**
* Session Cookie storage, magento_root/var directory used
* #var string
*/
const COOKIE_FILE = 'var/cookie';
/**
* Hostname
* #var string
*/
protected $_host = 'localhost';
/**
* Port
* #var int
*/
protected $_port = 80;
/**
* Stream resource
* #var object
*/
protected $_sock = null;
/**
* Request headers
* #var array
*/
protected $_headers = array();
/**
* Fields for POST method - hash
* #var array
*/
protected $_postFields = array();
/**
* Request cookies
* #var array
*/
protected $_cookies = array();
/**
* Response headers
* #var array
*/
protected $_responseHeaders = array();
/**
* Response body
* #var string
*/
protected $_responseBody = '';
/**
* Response status
* #var int
*/
protected $_responseStatus = 0;
/**
* Request timeout
* #var intunknown_type
*/
protected $_timeout = 300;
/**
* TODO
* #var int
*/
protected $_redirectCount = 0;
/**
* Curl
* #var object
*/
protected $_ch;
/**
* User ovverides options hash
* Are applied before curl_exec
*
* #var array();
*/
protected $_curlUserOptions = array();
/**
* User credentials
*
* #var array();
*/
protected $_auth = array();
/**
* Set request timeout, msec
*
* #param int $value
*/
public function setTimeout($value)
{
$this->_timeout = (int) $value;
}
/**
* Constructor
*/
public function __construct()
{
}
/**
* Destructor
* Removes temporary environment
*/
public function __destruct()
{
if (is_file(self::COOKIE_FILE)) {
#unlink(self::COOKIE_FILE);
}
}
/**
* Set headers from hash
* #param array $headers
*/
public function setHeaders($headers)
{
$this->_headers = $headers;
}
/**
* Add header
*
* #param $name name, ex. "Location"
* #param $value value ex. "http://google.com"
*/
public function addHeader($name, $value)
{
$this->_headers[$name] = $value;
}
/**
* Remove specified header
*
* #param string $name
*/
public function removeHeader($name)
{
unset($this->_headers[$name]);
}
/**
* Authorization: Basic header
* Login credentials support
*
* #param string $login username
* #param string $pass password
*/
public function setCredentials($login, $pass)
{
$this->_auth['login'] = $login;
$this->_auth['password'] = $pass;
//$val= base64_encode( "$login:$pass" );
//$this->addHeader( "Authorization", "Basic $val" );
}
/**
* Add cookie
*
* #param string $name
* #param string $value
*/
public function addCookie($name, $value)
{
$this->_cookies[$name] = $value;
}
/**
* Remove cookie
*
* #param string $name
*/
public function removeCookie($name)
{
unset($this->_cookies[$name]);
}
/**
* Set cookies array
*
* #param array $cookies
*/
public function setCookies($cookies)
{
$this->_cookies = $cookies;
}
/**
* Clear cookies
*/
public function removeCookies()
{
$this->setCookies(array());
}
/**
* Make GET request
*
* #param string $uri uri relative to host, ex. "/index.php"
*/
public function get($uri)
{
$this->makeRequest("GET", $uri);
}
/**
* Make POST request
* #see lib/Mage/HTTP/Mage_HTTP_Client#post($uri, $params)
*/
public function post($uri, $params)
{
$this->makeRequest("POST", $uri, $params);
}
/**
* Get response headers
*
* #return array
*/
public function getHeaders()
{
return $this->_responseHeaders;
}
/**
* Get response body
*
* #return string
*/
public function getBody()
{
return $this->_responseBody;
}
/**
* Get cookies response hash
*
* #return array
*/
public function getCookies()
{
if(empty($this->_responseHeaders['Set-Cookie'])) {
return array();
}
$out = array();
foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
$values = explode("; ", $row);
$c = count($values);
if(!$c) {
continue;
}
list($key, $val) = explode("=", $values[0]);
if(is_null($val)) {
continue;
}
$out[trim($key)] = trim($val);
}
return $out;
}
/**
* Get cookies array with details
* (domain, expire time etc)
* #return array
*/
public function getCookiesFull()
{
if(empty($this->_responseHeaders['Set-Cookie'])) {
return array();
}
$out = array();
foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
$values = explode("; ", $row);
$c = count($values);
if(!$c) {
continue;
}
list($key, $val) = explode("=", $values[0]);
if(is_null($val)) {
continue;
}
$out[trim($key)] = array('value'=>trim($val));
array_shift($values);
$c--;
if(!$c) {
continue;
}
for($i = 0; $i<$c; $i++) {
list($subkey, $val) = explode("=", $values[$i]);
$out[trim($key)][trim($subkey)] = trim($val);
}
}
return $out;
}
/**
* Get response status code
* #see lib/Mage/HTTP/Mage_HTTP_Client#getStatus()
*/
public function getStatus()
{
return $this->_responseStatus;
}
/**
* Make request
* #param string $method
* #param string $uri
* #param array $params
* #return null
*/
protected function makeRequest($method, $uri, $params = array())
{
static $isAuthorizationRequired = 0;
$this->_ch = curl_init();
// make request via secured layer
if ($isAuthorizationRequired && strpos($uri, 'https://') !== 0) {
$uri = str_replace('http://', '', $uri);
$uri = 'https://' . $uri;
}
$this->curlOption(CURLOPT_URL, $uri);
$this->curlOption(CURLOPT_SSL_VERIFYPEER, FALSE);
$this->curlOption(CURLOPT_SSL_VERIFYHOST, 2);
// force method to POST if secured
if ($isAuthorizationRequired) {
$method = 'POST';
}
if($method == 'POST') {
$this->curlOption(CURLOPT_POST, 1);
$postFields = is_array($params) ? $params : array();
if ($isAuthorizationRequired) {
$this->curlOption(CURLOPT_COOKIEJAR, self::COOKIE_FILE);
$this->curlOption(CURLOPT_COOKIEFILE, self::COOKIE_FILE);
$postFields = array_merge($postFields, $this->_auth);
}
if (!empty($postFields)) {
$this->curlOption(CURLOPT_POSTFIELDS, $postFields);
}
} elseif($method == "GET") {
$this->curlOption(CURLOPT_HTTPGET, 1);
} else {
$this->curlOption(CURLOPT_CUSTOMREQUEST, $method);
}
if(count($this->_headers)) {
$heads = array();
foreach($this->_headers as $k=>$v) {
$heads[] = $k.': '.$v;
}
$this->curlOption(CURLOPT_HTTPHEADER, $heads);
}
if(count($this->_cookies)) {
$cookies = array();
foreach($this->_cookies as $k=>$v) {
$cookies[] = "$k=$v";
}
$this->curlOption(CURLOPT_COOKIE, implode(";", $cookies));
}
if($this->_timeout) {
$this->curlOption(CURLOPT_TIMEOUT, $this->_timeout);
}
if($this->_port != 80) {
$this->curlOption(CURLOPT_PORT, $this->_port);
}
$this->curlOption(CURLOPT_RETURNTRANSFER, 1);
$this->curlOption(CURLOPT_FOLLOWLOCATION, 1);
$this->curlOption(CURLOPT_HEADERFUNCTION, array($this,'parseHeaders'));
if(count($this->_curlUserOptions)) {
foreach($this->_curlUserOptions as $k=>$v) {
$this->curlOption($k, $v);
}
}
$this->_responseHeaders = array();
$this->_responseBody = curl_exec($this->_ch);
$err = curl_errno($this->_ch);
if($err) {
$this->doError(curl_error($this->_ch));
}
if(!$this->getStatus()) {
return $this->doError("Invalid response headers returned from server.");
}
curl_close($this->_ch);
if (403 == $this->getStatus()) {
if (!$isAuthorizationRequired) {
$isAuthorizationRequired++;
$this->makeRequest($method, $uri, $params);
$isAuthorizationRequired=0;
} else {
return $this->doError(sprintf('Access denied for %s#%s', $_SESSION['auth']['login'], $uri));
}
}
}
/**
* Throw error excpetion
* #param $string
* #throws Exception
*/
public function isAuthorizationRequired()
{
if (isset($_SESSION['auth']['username']) && isset($_SESSION['auth']['password']) && !empty($_SESSION['auth']['username'])) {
return true;
}
return false;
}
/**
* Throw error excpetion
* #param $string
* #throws Exception
*/
public function doError($string)
{
throw new Exception($string);
}
/**
* Parse headers - CURL callback functin
*
* #param resource $ch curl handle, not needed
* #param string $data
* #return int
*/
protected function parseHeaders($ch, $data)
{
if(preg_match('/^HTTP\/[\d\.x]+ (\d+)/', $data, $m)) {
if (isset($m[1])) {
$this->_responseStatus = (int)$m[1];
}
} else {
$name = $value = '';
$out = explode(": ", trim($data), 2);
if(count($out) == 2) {
$name = $out[0];
$value = $out[1];
}
if(strlen($name)) {
if("Set-Cookie" == $name) {
if(!isset($this->_responseHeaders[$name])) {
$this->_responseHeaders[$name] = array();
}
$this->_responseHeaders[$name][] = $value;
} else {
$this->_responseHeaders[$name] = $value;
}
}
}
return strlen($data);
}
/**
* Set curl option directly
*
* #param string $name
* #param string $value
*/
protected function curlOption($name, $value)
{
curl_setopt($this->_ch, $name, $value);
}
/**
* Set curl options array directly
* #param array $array
*/
protected function curlOptions($array)
{
curl_setopt_array($this->_ch, $arr);
}
/**
* Set CURL options ovverides array *
*/
public function setOptions($arr)
{
$this->_curlUserOptions = $arr;
}
/**
* Set curl option
*/
public function setOption($name, $value)
{
$this->_curlUserOptions[$name] = $value;
}
}
Source

Fatal error: Call to a member function setFinalPrice() on a non-object in /app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php on line 89

I had installed an custom extension. Its running successfully and had all files at its place. But I am getting this error on my listing page
Fatal error: Call to a member function setFinalPrice() on a non-object in /var/zpanel/hostdata/zadmin/public_html/unisport_com/app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php on line 89.
I google this error but did'nt found any proper solution. One solution is to copy the original Abstract.php file may be because extension had overwrite this file. But I checked the code from the backup its the same and also copied original file but nothing worked for me.
What is wrong with this file? Can anybody help?
below is the code of Abstract.php file:
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* #category Mage
* #package Mage_Sales
* #copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Quote item abstract model
*
* Price attributes:
* - price - initial item price, declared during product association
* - original_price - product price before any calculations
* - calculation_price - prices for item totals calculation
* - custom_price - new price that can be declared by user and recalculated during calculation process
* - original_custom_price - original defined value of custom price without any convertion
*
* #category Mage
* #package Mage_Sales
* #author Magento Core Team <core#magentocommerce.com>
*/
abstract class Mage_Sales_Model_Quote_Item_Abstract extends Mage_Core_Model_Abstract
implements Mage_Catalog_Model_Product_Configuration_Item_Interface
{
/**
* Parent item for sub items for bundle product, configurable product, etc.
*
* #var Mage_Sales_Model_Quote_Item_Abstract
*/
protected $_parentItem = null;
/**
* Children items in bundle product, configurable product, etc.
*
* #var array
*/
protected $_children = array();
/**
*
* #var array
*/
protected $_messages = array();
/**
* Retrieve Quote instance
*
* #return Mage_Sales_Model_Quote
*/
abstract function getQuote();
/**
* Retrieve product model object associated with item
*
* #return Mage_Catalog_Model_Product
*/
public function getProduct()
{
$product = $this->_getData('product');
if ($product === null && $this->getProductId()) {
$product = Mage::getModel('catalog/product')
->setStoreId($this->getQuote()->getStoreId())
->load($this->getProductId());
$this->setProduct($product);
}
/**
* Reset product final price because it related to custom options
*/
$product->setFinalPrice(null);
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
/**
* Returns special download params (if needed) for custom option with type = 'file'
* Needed to implement Mage_Catalog_Model_Product_Configuration_Item_Interface.
* Return null, as quote item needs no additional configuration.
*
* #return null|Varien_Object
*/
public function getFileDownloadParams()
{
return null;
}
/**
* Specify parent item id before saving data
*
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
protected function _beforeSave()
{
parent::_beforeSave();
if ($this->getParentItem()) {
$this->setParentItemId($this->getParentItem()->getId());
}
return $this;
}
/**
* Set parent item
*
* #param Mage_Sales_Model_Quote_Item $parentItem
* #return Mage_Sales_Model_Quote_Item
*/
public function setParentItem($parentItem)
{
if ($parentItem) {
$this->_parentItem = $parentItem;
$parentItem->addChild($this);
}
return $this;
}
/**
* Get parent item
*
* #return Mage_Sales_Model_Quote_Item
*/
public function getParentItem()
{
return $this->_parentItem;
}
/**
* Get chil items
*
* #return array
*/
public function getChildren()
{
return $this->_children;
}
/**
* Add child item
*
* #param Mage_Sales_Model_Quote_Item_Abstract $child
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function addChild($child)
{
$this->setHasChildren(true);
$this->_children[] = $child;
return $this;
}
/**
* Adds message(s) for quote item. Duplicated messages are not added.
*
* #param mixed $messages
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function setMessage($messages)
{
$messagesExists = $this->getMessage(false);
if (!is_array($messages)) {
$messages = array($messages);
}
foreach ($messages as $message) {
if (!in_array($message, $messagesExists)) {
$this->addMessage($message);
}
}
return $this;
}
/**
* Add message of quote item to array of messages
*
* #param string $message
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function addMessage($message)
{
$this->_messages[] = $message;
return $this;
}
/**
* Get messages array of quote item
*
* #param bool $string flag for converting messages to string
* #return array|string
*/
public function getMessage($string = true)
{
if ($string) {
return join("\n", $this->_messages);
}
return $this->_messages;
}
/**
* Removes message by text
*
* #param string $text
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function removeMessageByText($text)
{
foreach ($this->_messages as $key => $message) {
if ($message == $text) {
unset($this->_messages[$key]);
}
}
return $this;
}
/**
* Clears all messages
*
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function clearMessage()
{
$this->unsMessage(); // For older compatibility, when we kept message inside data array
$this->_messages = array();
return $this;
}
/**
* Retrieve store model object
*
* #return Mage_Core_Model_Store
*/
public function getStore()
{
return $this->getQuote()->getStore();
}
/**
* Checking item data
*
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function checkData()
{
$this->setHasError(false);
$this->clearMessage();
$qty = $this->_getData('qty');
try {
$this->setQty($qty);
} catch (Mage_Core_Exception $e) {
$this->setHasError(true);
$this->setMessage($e->getMessage());
} catch (Exception $e) {
$this->setHasError(true);
$this->setMessage(Mage::helper('sales')->__('Item qty declaration error.'));
}
try {
$this->getProduct()->getTypeInstance(true)->checkProductBuyState($this->getProduct());
} catch (Mage_Core_Exception $e) {
$this->setHasError(true)
->setMessage($e->getMessage());
$this->getQuote()->setHasError(true)
->addMessage(Mage::helper('sales')->__('Some of the products below do not have all the required options.'));
} catch (Exception $e) {
$this->setHasError(true)
->setMessage(Mage::helper('sales')->__('Item options declaration error.'));
$this->getQuote()->setHasError(true)
->addMessage(Mage::helper('sales')->__('Items options declaration error.'));
}
if ($this->getProduct()->getHasError()) {
$this->setHasError(true)
->setMessage(Mage::helper('sales')->__('Some of the selected options are not currently available.'));
$this->getQuote()->setHasError(true)
->addMessage($this->getProduct()->getMessage(), 'options');
}
if ($this->getHasConfigurationUnavailableError()) {
$this->setHasError(true)
->setMessage(Mage::helper('sales')->__('Selected option(s) or their combination is not currently available.'));
$this->getQuote()->setHasError(true)
->addMessage(Mage::helper('sales')->__('Some item options or their combination are not currently available.'), 'unavailable-configuration');
$this->unsHasConfigurationUnavailableError();
}
return $this;
}
/**
* Get original (not related with parent item) item quantity
*
* #return int|float
*/
public function getQty()
{
return $this->_getData('qty');
}
/**
* Get total item quantity (include parent item relation)
*
* #return int|float
*/
public function getTotalQty()
{
if ($this->getParentItem()) {
return $this->getQty()*$this->getParentItem()->getQty();
}
return $this->getQty();
}
/**
* Calculate item row total price
*
* #return Mage_Sales_Model_Quote_Item
*/
public function calcRowTotal()
{
$qty = $this->getTotalQty();
// Round unit price before multiplying to prevent losing 1 cent on subtotal
$total = $this->getStore()->roundPrice($this->getCalculationPriceOriginal()) * $qty;
$baseTotal = $this->getStore()->roundPrice($this->getBaseCalculationPriceOriginal()) * $qty;
$this->setRowTotal($this->getStore()->roundPrice($total));
$this->setBaseRowTotal($this->getStore()->roundPrice($baseTotal));
return $this;
}
/**
* Get item price used for quote calculation process.
* This method get custom price (if it is defined) or original product final price
*
* #return float
*/
public function getCalculationPrice()
{
$price = $this->_getData('calculation_price');
if (is_null($price)) {
if ($this->hasCustomPrice()) {
$price = $this->getCustomPrice();
} else {
$price = $this->getConvertedPrice();
}
$this->setData('calculation_price', $price);
}
return $price;
}
/**
* Get item price used for quote calculation process.
* This method get original custom price applied before tax calculation
*
* #return float
*/
public function getCalculationPriceOriginal()
{
$price = $this->_getData('calculation_price');
if (is_null($price)) {
if ($this->hasOriginalCustomPrice()) {
$price = $this->getOriginalCustomPrice();
} else {
$price = $this->getConvertedPrice();
}
$this->setData('calculation_price', $price);
}
return $price;
}
/**
* Get calculation price used for quote calculation in base currency.
*
* #return float
*/
public function getBaseCalculationPrice()
{
if (!$this->hasBaseCalculationPrice()) {
if ($this->hasCustomPrice()) {
$price = (float) $this->getCustomPrice();
if ($price) {
$rate = $this->getStore()->convertPrice($price) / $price;
$price = $price / $rate;
}
} else {
$price = $this->getPrice();
}
$this->setBaseCalculationPrice($price);
}
return $this->_getData('base_calculation_price');
}
/**
* Get original calculation price used for quote calculation in base currency.
*
* #return float
*/
public function getBaseCalculationPriceOriginal()
{
if (!$this->hasBaseCalculationPrice()) {
if ($this->hasOriginalCustomPrice()) {
$price = (float) $this->getOriginalCustomPrice();
if ($price) {
$rate = $this->getStore()->convertPrice($price) / $price;
$price = $price / $rate;
}
} else {
$price = $this->getPrice();
}
$this->setBaseCalculationPrice($price);
}
return $this->_getData('base_calculation_price');
}
/**
* Get whether the item is nominal
* TODO: fix for multishipping checkout
*
* #return bool
*/
public function isNominal()
{
if (!$this->hasData('is_nominal')) {
$this->setData('is_nominal', $this->getProduct() ? '1' == $this->getProduct()->getIsRecurring() : false);
}
return $this->_getData('is_nominal');
}
/**
* Data getter for 'is_nominal'
* Used for converting item to order item
*
* #return int
*/
public function getIsNominal()
{
return (int)$this->isNominal();
}
/**
* Get original price (retrieved from product) for item.
* Original price value is in quote selected currency
*
* #return float
*/
public function getOriginalPrice()
{
$price = $this->_getData('original_price');
if (is_null($price)) {
$price = $this->getStore()->convertPrice($this->getBaseOriginalPrice());
$this->setData('original_price', $price);
}
return $price;
}
/**
* Set original price to item (calculation price will be refreshed too)
*
* #param float $price
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function setOriginalPrice($price)
{
return $this->setData('original_price', $price);
}
/**
* Get Original item price (got from product) in base website currency
*
* #return float
*/
public function getBaseOriginalPrice()
{
return $this->_getData('base_original_price');
}
/**
* Specify custom item price (used in case whe we have apply not product price to item)
*
* #param float $value
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function setCustomPrice($value)
{
$this->setCalculationPrice($value);
$this->setBaseCalculationPrice(null);
return $this->setData('custom_price', $value);
}
/**
* Get item price. Item price currency is website base currency.
*
* #return decimal
*/
public function getPrice()
{
return $this->_getData('price');
}
/**
* Specify item price (base calculation price and converted price will be refreshed too)
*
* #param float $value
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function setPrice($value)
{
$this->setBaseCalculationPrice(null);
$this->setConvertedPrice(null);
return $this->setData('price', $value);
}
/**
* Get item price converted to quote currency
* #return float
*/
public function getConvertedPrice()
{
$price = $this->_getData('converted_price');
if (is_null($price)) {
$price = $this->getStore()->convertPrice($this->getPrice());
$this->setData('converted_price', $price);
}
return $price;
}
/**
* Set new value for converted price
* #param float $value
* #return Mage_Sales_Model_Quote_Item_Abstract
*/
public function setConvertedPrice($value)
{
$this->setCalculationPrice(null);
$this->setData('converted_price', $value);
return $this;
}
/**
* Clone quote item
*
* #return Mage_Sales_Model_Quote_Item
*/
public function __clone()
{
$this->setId(null);
$this->_parentItem = null;
$this->_children = array();
$this->_messages = array();
return $this;
}
/**
* Checking if there children calculated or parent item
* when we have parent quote item and its children
*
* #return bool
*/
public function isChildrenCalculated()
{
if ($this->getParentItem()) {
$calculate = $this->getParentItem()->getProduct()->getPriceType();
} else {
$calculate = $this->getProduct()->getPriceType();
}
if ((null !== $calculate) && (int)$calculate === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
return true;
}
return false;
}
/**
* Checking can we ship product separatelly (each child separately)
* or each parent product item can be shipped only like one item
*
* #return bool
*/
public function isShipSeparately()
{
if ($this->getParentItem()) {
$shipmentType = $this->getParentItem()->getProduct()->getShipmentType();
} else {
$shipmentType = $this->getProduct()->getShipmentType();
}
if ((null !== $shipmentType) &&
(int)$shipmentType === Mage_Catalog_Model_Product_Type_Abstract::SHIPMENT_SEPARATELY) {
return true;
}
return false;
}
/**
* Calculate item tax amount
*
* #deprecated logic moved to tax totals calculation model
* #return Mage_Sales_Model_Quote_Item
*/
public function calcTaxAmount()
{
$store = $this->getStore();
if (!Mage::helper('tax')->priceIncludesTax($store)) {
if (Mage::helper('tax')->applyTaxAfterDiscount($store)) {
$rowTotal = $this->getRowTotalWithDiscount();
$rowBaseTotal = $this->getBaseRowTotalWithDiscount();
} else {
$rowTotal = $this->getRowTotal();
$rowBaseTotal = $this->getBaseRowTotal();
}
$taxPercent = $this->getTaxPercent()/100;
$this->setTaxAmount($store->roundPrice($rowTotal * $taxPercent));
$this->setBaseTaxAmount($store->roundPrice($rowBaseTotal * $taxPercent));
$rowTotal = $this->getRowTotal();
$rowBaseTotal = $this->getBaseRowTotal();
$this->setTaxBeforeDiscount($store->roundPrice($rowTotal * $taxPercent));
$this->setBaseTaxBeforeDiscount($store->roundPrice($rowBaseTotal * $taxPercent));
} else {
if (Mage::helper('tax')->applyTaxAfterDiscount($store)) {
$totalBaseTax = $this->getBaseTaxAmount();
$totalTax = $this->getTaxAmount();
if ($totalTax && $totalBaseTax) {
$totalTax -= $this->getDiscountAmount() * ($this->getTaxPercent() / 100);
$totalBaseTax -= $this->getBaseDiscountAmount() * ($this->getTaxPercent() / 100);
$this->setBaseTaxAmount($store->roundPrice($totalBaseTax));
$this->setTaxAmount($store->roundPrice($totalTax));
}
}
}
if (Mage::helper('tax')->discountTax($store) && !Mage::helper('tax')->applyTaxAfterDiscount($store)) {
if ($this->getDiscountPercent()) {
$baseTaxAmount = $this->getBaseTaxBeforeDiscount();
$taxAmount = $this->getTaxBeforeDiscount();
$baseDiscountDisposition = $baseTaxAmount/100*$this->getDiscountPercent();
$discountDisposition = $taxAmount/100*$this->getDiscountPercent();
$this->setDiscountAmount($this->getDiscountAmount()+$discountDisposition);
$this->setBaseDiscountAmount($this->getBaseDiscountAmount()+$baseDiscountDisposition);
}
}
return $this;
}
/**
* Get item tax amount
*
* #deprecated
* #return decimal
*/
public function getTaxAmount()
{
return $this->_getData('tax_amount');
}
/**
* Get item base tax amount
*
* #deprecated
* #return decimal
*/
public function getBaseTaxAmount()
{
return $this->_getData('base_tax_amount');
}
/**
* Get item price (item price always exclude price)
*
* #deprecated
* #return decimal
*/
protected function _calculatePrice($value, $saveTaxes = true)
{
$store = $this->getQuote()->getStore();
if (Mage::helper('tax')->priceIncludesTax($store)) {
$bAddress = $this->getQuote()->getBillingAddress();
$sAddress = $this->getQuote()->getShippingAddress();
$address = $this->getAddress();
if ($address) {
switch ($address->getAddressType()) {
case Mage_Sales_Model_Quote_Address::TYPE_BILLING:
$bAddress = $address;
break;
case Mage_Sales_Model_Quote_Address::TYPE_SHIPPING:
$sAddress = $address;
break;
}
}
if ($this->getProduct()->getIsVirtual()) {
$sAddress = $bAddress;
}
$priceExcludingTax = Mage::helper('tax')->getPrice(
$this->getProduct()->setTaxPercent(null),
$value,
false,
$sAddress,
$bAddress,
$this->getQuote()->getCustomerTaxClassId(),
$store
);
$priceIncludingTax = Mage::helper('tax')->getPrice(
$this->getProduct()->setTaxPercent(null),
$value,
true,
$sAddress,
$bAddress,
$this->getQuote()->getCustomerTaxClassId(),
$store
);
if ($saveTaxes) {
$qty = $this->getQty();
if ($this->getParentItem()) {
$qty = $qty*$this->getParentItem()->getQty();
}
if (Mage::helper('tax')->displayCartPriceInclTax($store)) {
$rowTotal = $value*$qty;
$rowTotalExcTax = Mage::helper('tax')->getPrice(
$this->getProduct()->setTaxPercent(null),
$rowTotal,
false,
$sAddress,
$bAddress,
$this->getQuote()->getCustomerTaxClassId(),
$store
);
$rowTotalIncTax = Mage::helper('tax')->getPrice(
$this->getProduct()->setTaxPercent(null),
$rowTotal,
true,
$sAddress,
$bAddress,
$this->getQuote()->getCustomerTaxClassId(),
$store
);
$totalBaseTax = $rowTotalIncTax-$rowTotalExcTax;
$this->setRowTotalExcTax($rowTotalExcTax);
}
else {
$taxAmount = $priceIncludingTax - $priceExcludingTax;
$this->setTaxPercent($this->getProduct()->getTaxPercent());
$totalBaseTax = $taxAmount*$qty;
}
$totalTax = $this->getStore()->convertPrice($totalBaseTax);
$this->setTaxBeforeDiscount($totalTax);
$this->setBaseTaxBeforeDiscount($totalBaseTax);
$this->setTaxAmount($totalTax);
$this->setBaseTaxAmount($totalBaseTax);
}
$value = $priceExcludingTax;
}
return $value;
}
}

symfony2 self referencing entity has validation problems

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

Resources