With Api-Platform, exposing Doctrine Entities is quite easy and works very well but I don't see how to create custom entrypoint without entities just to call an external service and get its data or do complex treatments
I saw this post (API Platform - Which approach should I use for creating custom operation without entity) but I don't want to create a POST method just to insert my logic in a data persister.
If i just want to create one entrypoint /getMyCustomData with the GET method and without passing any parameter, what should I do?
I looked at swagger decorators but if I understand, it works on an existing entity.
you can create just a normal controller in Symfony.
/**
* #Route("/getMyCustomData", methods={"GET"}, name="my_api_custom_data")
* #param Request $request
* #return Response
*/
public function getMyCustomDataAction(Request $request): Response
{
/** your code **/
}
Related
I am writing REST API, where resources are entities. There is a problem with Id field, which has NoBlank and NotNull constraints (which are logical) when creating new entity - obviously a new entity has no Id before writing to DB. However validation component of course says the entity is not valid. How to overcome this issue without removing the constraints from the Id field?
In my opinion you shouldn't have a constraint on your id.
Url of create should be [POST]/resource and url of edit should be [PUT]/resource/{id}.
(Or POST/PATCH depending on how strictly you are doing rest HTTP methods)
THis way the id is always mandatory.
If you don't want this routing logic, you can use validation groups
/**
* #Assert\NotNull(groups={"create"})
*/
private $id;
/**
* #Assert\NotNull(groups={"create","edit"})
*/
private $whatever;
I would like to use the htmlpurifier not as a form data transformer, but rather as an annotation in the entities property.
The problem: In the Symfony 2.8 project we use a lot of different types of forms, some using symfonies formbuilder, some via sonata-admin, some using twig and ajax etc ..
So using a transformer and a custom field type is not the way to go.
Also, editing every single create or update action would be overkill.
I've been playing with the idea of an event listener on prePersist, but with such a large amount of different entities in our project we would most likely incur a performance hit if this were to be called on every persist() action. Limiting it to only specific object types would also be painstaking.
Is it possible to use the htmlpurifier bundle as an annotation only on the properties that matter?
eg:
/**
* #var string
*
* #ORM\Column(name="uprename", length=20, nullable=true)
* #htmlpurifier('default')
*/
private $firstName;
Where default would be the default configuration.
bundle: https://github.com/Exercise/HTMLPurifierBundle
In the Symfony documentation about Embed forms, I just read this :
class Task{
/**
* #Assert\Type(type="AppBundle\Entity\Category")
* #Assert\Valid()
*/
protected $category;
// ...
}
They later say that
The Category instance is accessible naturally via $task->getCategory()
and can be persisted to the database or used however you need.
How is that different from a Many-To-One mapping ? (many tasks for one category of course)
Well, ORM mapping map the php class to the doctrine metadata.
Assert is a mecanism to validate objects.
It means you could use assert on objects wich are not entities or you could not use a mapped field in your formType
ManyToOne map an object to another from the doctrine point of view.
Assert\Type indicate that this attribute of your form is validated like another related object, wich is Category
I am starting to develop with symfony 2 and it uses a lot dependency injection. I would like to know if is there any way that makes netbeans detect the type of object based on the string and auto complete with their methods?
For example, $this->container->get('doctrine') returns a Doctrine\Bundle\DoctrineBundle\Registry instance. In the container, the key doctrine corresponds to Doctrine\Bundle\DoctrineBundle\Registry.
Something like it, could be useful for zendframework 2 also.
I don't want to create new methods in the controller and nor use /* #var $var Symfony...*/, I would automatic detection.
As far as I know, there's no way for an IDE to detect the type of the object your container returns. My solution is to wrap those calls to the container into private getter functions. IMHO this improves code readability as well – especially, if you do this call more than once per class.
/**
* #return \Doctrine\Bundle\DoctrineBundle\Registry
*/
private function getDoctrine()
{
return $this->container->get('doctrine');
}
The IDE "PhpStorm" permits to suggest "use" declarations.
And this IDE propose specific features for Symfony2 and Drupal !
edited by JetBrains : http://www.jetbrains.com/phpstorm/
Not free but power full enough to reduce time developpement time (and time is money...)
Enjoy : )
phpStorm:
$foobar= $this->get('foobar'); //returns mixed
/* #var \MyNamespace\FooBar $foobar*/
or
$foobar= $this->get('foobar'); //returns mixed
/* #var FooBar $foobar*/
You can do this with eclipse PDT:
$foobar= $this->get('foobar'); //returns mixed
/* #var $foobar \MyNamespace\FooBar*/
( Walk around ) When comes to Symfony services:
Instead of
$doctrine = $this->container->get('doctrine');
use
$doctrine = $this->getDoctrine();
As you can see, Symfony allows you to access most of it services directly from $this variable. NetBeans will know what auto completion to use.
Lets have a look why this works (inside Controller class)
It is possible because Controller class imports Registry class with USE statement,
use Doctrine\Bundle\DoctrineBundle\Registry;
and then in method comment annotation it declares the returning object type with
/*
* #return Registry
*/
If you call $this->container->get('doctrine'); directly then auto completion will be get omitted and you will have to use whats below.
( Answer ) No magic auto completion works so far. Use Php Storm (it does what you request). For those who pick to stick with NetBeans you need to use manual annotation like in example below:
We can point NetBeans to a class it should be using for auto completion.
1) In terminal from project directory search for service you want to import:
php bin/console debug:container
If you know what you looking for use this instead:
php bin/console d:container | grep doctrine
...
doctrine --------------------------------------------------------
Doctrine\Bundle\DoctrineBundle\Registry
...
2) If this is not a service use get_class() PHP build in function to get class name of the object it particular variable. Or use reflection class. It's up to you.
3) Once you know the class name declare USE statement for better readability
use Doctrine\Bundle\DoctrineBundle\Registry;
4) Now wen we know what is the class name of the object instance in particular variable we are ready to inform NetBeans about what we know by using comment annotations so that it can enable auto completion.
/**
* #var $doctrine Registry
*/
$doctrine = $this->container->get('doctrine');
Now auto completion is enabled. Type
$doctrine->|
then press Ctrl+Space. See the image below:
A Symfony2 application has a Job entity which has a tasks property, a collection of Task entities.
Job->getTasks() is used to iterate over a given job's collection of tasks. The Task entities encapsulated in the tasks property are lazy-loaded by Doctrine. I'm guessing they're loaded at the point getTasks() is called.
With extra details removed, the Job entity looks something like this:
<?php
class Job
{
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\OneToMany(targetEntity="Example\Bundle\Entity\Task\Task", mappedBy="job")
*/
private $tasks;
public function __construct()
{
$this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #return Doctrine\Common\Collections\Collection
*/
public function getTasks()
{
return $this->tasks;
}
}
I often need to access only a subset of all tasks (maybe 10 out of 1000) for a job and currently do so by iterating over getTasks() and picking out those with relevant ids.
For large collections of tasks (thousands, tens of thousands) it can take a long time for the tasks collection to be loaded from the database.
I'd like to reduce the time required to gain access to a subset of tasks. I can do so by using a custom entity repository to retrieve Task entities by id and job.
I'd like to know if a in-built feature of Symfony2 and/or Doctrine2 already exists for doing this.
My thinking is that an entity with a related collection of entities is a common situation (blog post and comments, for example) and that there may be some pagination-related concept at the entity level for retrieving only a subset of related entities.
Is there an in-built Symfony2 feature for what I need?
Update1:
I'd ideally like to be able to still iterate over Job->getTasks() knowing that it will return only a subset of tasks that I have somehow specified.
I think you are looking for Extra Lazy Association.