Filters do not apply - symfony

I have filters, but they do not apply to data
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\Collection;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
/**
* #ORM\Entity(repositoryClass="App\Repository\HostRepository")
*
* #ApiResource(
* routePrefix="/profile"
* )
*
* #ApiFilter(SearchFilter::class, properties={"id": "exact"})
*
*/
class Host
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
.....
I send such a request
http://localhost/api/profile/hosts?id=1
All answers are returned to me (including id = 1)
Same result with 'name' and other parameters
What could be the problem?

This is not indicated in the documentation. But the filter will not work until you specify in the file api_platform.yaml
framework:
serializer: { enable_annotations: true }
As correctly noted in the comments, this is mentioned in the documentation in the configuration section:
api-platform.com/docs/core/serialization#configuration

Related

Default API Filters Failing when referencing nested properties of related entities

I am configuring a series of ApiFilter classes from the Api-platform stack in a Symfony 4 application. I am finding that any filters using a nested property from an entity relationship takes no effect. Please see my example code below, would really appreciate any assistance with why it may not be working.
The entity I am trying to filter on is:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiProperty;
/**
* PostAuthor
* #ApiResource()
* #ORM\Table(name="POST_AUTHOR", indexes={#ORM\Index(name="IDX_CF3397D94A7000A0", columns={"IDENTITY_ID"})})
* #ORM\Entity(repositoryClass="App\Repository\PostAuthorRepository")
*/
class PostAuthor
{
/**
* #var string
*
* #ORM\Column(name="USER_ID", type="string", length=255, nullable=false)
* #ORM\Id
*/
private $userId;
/**
* #var string
*
* #ORM\Column(name="USERNAME", type="string", length=255, nullable=false)
*/
private $username;
And the collection I am filtering is:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiFilter;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\NumericFilter;
use Doctrine\ORM\Mapping as ORM;
/**
* PostHeader
* #ORM\Table(name="POST_HEADER", indexes={#ORM\Index(name="IDX_1CEEE7D0B65E5FF8", columns={"EMOTION_REF_ID"}), #ORM\Index(name="IDX_1CEEE7D08AFAAB14", columns={"AUTHOR_ID"})})
* #ORM\Entity(repositoryClass="App\Repository\PostHeaderRepository")
* #ApiResource(
* normalizationContext={"groups"={"postheader:read"}},
* denormalizationContext={"groups"={"postheader:write"}},
* )
* #ApiFilter(SearchFilter::class, properties={"author.userId": "partial", "author.username": "partial"})
*/
class PostHeader
{
/**
* #var PostAuthor
*
* #ORM\ManyToOne(targetEntity="PostAuthor")
* #ORM\JoinColumns({#ORM\JoinColumn(name="AUTHOR_ID", referencedColumnName="USER_ID")})
* #Groups({"postheader:read"})
*/
private $author;
I just test on a new project with the same classes than you and it works. I can filter by author.userId.
Please give us your testing request. And the error message ;).

Undefined index: email with fosuserbundle

I have an existing app installed from git repo and know he should work, but having problems with launching it. App uses fosuserbundle
and I'm getting following error on both login/sign up:
Undefined index: email in /var/www/relabld-old/website/vendor /doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php on line 1704
although email field exists in my User class:
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Index;
use Doctrine\Common\Collections\ArrayCollection as ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints as Assert;
use Relabld\CommonBundle\Entity\UserStatus;
use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList;
use Doctrine\Common\Collections\Criteria;
use Relabld\CommonBundle\Entity\ItemStatus;
use Relabld\CommonBundle\Validator\Constraints as CustomAssert;
/**
* #ORM\Entity(repositoryClass="Relabld\CommonBundle\Entity\UserRepository")
* #ORM\Table(name="fos_user", indexes={#ORM\Index(name="first_name_idx", columns={"firstName"}), #ORM\Index(name="last_name_idx", columns={"lastName"}) , #ORM\Index(name="full_name_idx", columns={"fullName"})} )
* #UniqueEntity(fields={"email"}, groups={"Registration","Basics"}, message="Email is already used")
* #UniqueEntity(fields={"username"}, groups={"Registration"})
* #ORM\HasLifecycleCallbacks
* #CustomAssert\CustomUser
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* groups={"requestInvitation"}
* )
*/
protected $email;
...
What could be the reason of this?
Delete email field, this field already exists.

Custom JSON serializers for a Symfony 3 entity

I have a Symfony 3.2 entity using Doctrine's Translatable extension.
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Media
*
* #ORM\Table(name="medias")
* #Gedmo\TranslationEntity(class="AppBundle\Entity\Translation\MediaTranslation")
*/
class Media implements Translatable
{
/* [...] */
/**
* #var string|null
*
* #ORM\Column(type="text", nullable=true)
* #Gedmo\Translatable
* #Groups({"single_media"})
*/
private $description;
/* [...] */
}
I know how to use the basic way to serialize this entity in JSON (I use friendsofsymfony/rest-bundle for the serialization of my REST API), but I would like to serialize it in a custom way like this...
{
"description": {
"fr": "description en français",
"en": "english description",
}
}
try this :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Media
*
* #ORM\Table(name="medias")
* #Gedmo\TranslationEntity(class="AppBundle\Entity\Translation\MediaTranslation")
*/
class Media implements Translatable, \Serializable
{
/* [...] */
/**
* #var string|null
*
* #ORM\Column(type="text", nullable=true)
* #Gedmo\Translatable
* #Groups({"single_media"})
*/
private $description;
/* [...] */
}

Why does Doctrine update related entities, after JMS deserialize

I'm using Doctrine+JMSserializer in Symfony2 project, just found a problem that related entities and their data could be compromised during typical JMS "deserialize" and Doctrine "persist" operation.
$data = [
'locale' => 'en',
'name' => $this->faker->sentence(),
'content' => $this->faker->text(),
'subject' => [
'id' => $page->getId(),
'name' => 'new name' // <-- compromised property
]
];
$rawPayload = json_encode($data);
$entity = $this->serializer->deserialize(
$rawPayload,
$resolvedClass,
'json'
);
and after typical persist operation for new $entity related Page entity name, being change - so its a problem.
$this->getEntityManager()->persist($entity);
$this->getEntityManager()->flush();
The goal is to set page Id for the review, but prevent change for other properties, otherwise Page entity can be compromised. I tried to solve this issue changing annotations, doctrine settings, etc..
Any ideas how to solve this issue in natural way?
Review and Page entites:
use Aisel\ReviewBundle\Entity\Review as BaseReview;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation as JMS;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Review
*
* #ORM\HasLifecycleCallbacks()
* #ORM\Table(name="aisel_page_review")
* #ORM\Entity(repositoryClass="Aisel\ResourceBundle\Repository\CollectionRepository")
* #JMS\ExclusionPolicy("all")
*/
class Review extends BaseReview
{
/**
* #var Page
* #Assert\NotNull()
* #ORM\ManyToOne(targetEntity="Aisel\PageBundle\Entity\Page", inversedBy="pages")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="page_id", referencedColumnName="id", nullable=false)
* })
* #JMS\Type("Aisel\PageBundle\Entity\Page")
* #JMS\Expose
* #JMS\MaxDepth(2)
*/
private $subject;
/**
* #return Page
*/
public function getSubject()
{
return $this->subject;
}
/**
* #param Page $subject
*/
public function setSubject($subject)
{
$this->subject = $subject;
}
}
<?php
namespace Aisel\PageBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use JMS\Serializer\Annotation as JMS;
use Aisel\ResourceBundle\Domain\UrlInterface;
use Aisel\PageBundle\Entity\Node;
use Aisel\PageBundle\Entity\Review;
use Aisel\UserBundle\Entity\User;
use Aisel\ResourceBundle\Domain\IdTrait;
use Aisel\ResourceBundle\Domain\UpdateCreateTrait;
use Aisel\ResourceBundle\Domain\MetaTrait;
use Aisel\ResourceBundle\Domain\LocaleTrait;
use Aisel\ResourceBundle\Domain\StatusTrait;
use Aisel\ResourceBundle\Domain\NameTrait;
use Aisel\ResourceBundle\Domain\ContentTrait;
use Aisel\ResourceBundle\Domain\CommentStatusTrait;
/**
* Page
*
* #author Ivan Proskuryakov <volgodark#gmail.com>
*
* #ORM\HasLifecycleCallbacks()
* #ORM\Table(name="aisel_page")
* #ORM\Entity(repositoryClass="Aisel\ResourceBundle\Repository\CollectionRepository")
* #JMS\ExclusionPolicy("all")
*/
class Page implements UrlInterface
{
use IdTrait;
use NameTrait;
use ContentTrait;
use LocaleTrait;
use StatusTrait;
use CommentStatusTrait;
use MetaTrait;
use UpdateCreateTrait;
/**
* #var ArrayCollection
* #ORM\ManyToMany(targetEntity="Aisel\PageBundle\Entity\Node")
* #ORM\JoinTable(
* name="aisel_page_page_node",
* joinColumns={#ORM\JoinColumn(name="page_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="node_id", referencedColumnName="id")}
* )
* #JMS\Type("ArrayCollection<Aisel\PageBundle\Entity\Node>")
* #JMS\Expose
* #JMS\MaxDepth(2)
* #JMS\Groups({"collection","details"})
*/
private $nodes;
/**
* #var ArrayCollection<Aisel\PageBundle\Entity\Review>
* #ORM\OneToMany(targetEntity="Aisel\PageBundle\Entity\Review", mappedBy="subject", cascade={"remove"})
* #ORM\OrderBy({"createdAt" = "DESC"})
* #JMS\Expose
* #JMS\MaxDepth(2)
* #JMS\Type("ArrayCollection<Aisel\PageBundle\Entity\Review>")
* #JMS\Groups({"collection","details"})
*/
private $reviews;

I give not a valid entity or mapped super class

i am trying to create entity via cli. When i try to cretate getter/setter via console it gives this error: Doctrin\ORM\Mapping\MappingException
Class SfTuts\JobeetBundle\Entity\Job is not valid entity or mapped super class
Here is my code:
<?php
namespace SfTuts\JobeetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="job")
*/
class Job
{
/**
* #ORM\Id #Column(type="integer")
* #ORM\GeneratedValue
*/
protected $id;
}
How can i solve this problem? Where is my fault? Thanks.
Check do you have this option in your config.yml file
doctrine:
orm:
auto_mapping: true
Also your column declaration is wrong. It should be #ORM\Column not #Column becouse you are using Doctrine\ORM\Mapping namespace for annotations, not SfTuts\JobeetBundle\Entity
namespace SfTuts\JobeetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="job")
*/
class Job
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
protected $id;
}

Resources