This is my environment :
I have an entity :
Object
|____ id (integer)
|____ foo (string)
|____ configurations (collection)
The property configurations
is a collection of Configuration
entities mapped with a oneToMany
. Anyway, that looks like this :
Configuration
|____ id (integer)
|____ bar (string)
|____ name (string, nullable)
I have a service to get a single object
:
This service is in a bundle which manage objects of many projects.
This service is not aware of which project call it.
This service is a set of filters, events listeners and sql queries. (something about 2K lines)
Consider I can't / don't want to update its get process for what I want to do here.
I have the single action that I want to act on in my controller like this :
$objMgr = $this->get('objectManager'); //get my service I talked before
$object = $objMgr->findOneById(); //get my object
return array('object' => $object);// render template
I have lots of themes managing the end user screen with a twig file in each :
theme1
|____ object_details.html.twig
theme2
|____ object_details.html.twig
themeX
|____ object_details.html.twig
These object_details.html.twig
have this code to print the configurations.
{% for config in object.configurations %}
{# div config.blablabla etc. #}
{% endfor %}
According to the context above, can I exclude all configurations with a name
property not null ?
The answer doesn't edit the twig files (I know how to do that ^^)
I want to be sure that the exclusion of a configuration
, will not be detected by doctrine and it deletes this config
of my database on a random flush somewhere in the code.
The answer can be : "Dude, we can't do that". In fact, I'm very curious to know if it's possible. I have no idea at the moment.
The answer must respect some best practices :)
Comments anticipation : Why not edit twig files ? : I have lots of themes, I want to know if it's possible to do it once.
Why not exclude results in your db query ? : Because I want these configurations in my other pages and projects using this getter.
+50 for the best try :)
What you want is filtering by criteria:
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-collections
And an example:
// Entity class
class Department
{
public function getEmployeesByEmployeeTypeId($employeeTypeId)
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('employeeType', $employeeTypeId));
return $this->employees->matching($criteria);
}
}
in your case criteria would be like
$criteria->where("name is not null");
return $this->configurations->matching($criteria);
building on my comments above:
One option, that would not reflect on anything but the view, would be to implement a (configurable) decorator that exposes the same api as the original object.
This way the view, or maybe even other consumers wouldn't even know that they are dealing with a special case.
For example:
<?php
namespace App\Something;
use Doctrine\Common\Collections\Criteria;
class ObjectDecorator /* implement ObjectInterface // if needed */
{
public function __construct(Object $object)
{
$this->base = $object;
}
public function getConfigurations()
{
//Using Criteria to make it cleaner than a loop.
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->isNull('name'));
return $this->base->getConfigurations()->matching($criteria);
}
/*
Override all your decorated entity getters with
public function getFoo()
{
return $this->base->getFoo();
}
*/
}
and in your controller use:
return array('object' => new ObjectDecorator($object));
You could extend this a number of ways:
I do not really understand the whole problem, but I understand you want to get some items from a list in an entity and do not want to remove from the object for some reason. So, create a new function directly in the entity, in this function you can filter the list, and then return the new collection. In that way you do not compromises the object.
/**
* Object
*
* @ORM\Table()
* @ORM\Entity
*/
class Object
{
/**
* @var Collection
*
* @ORM\OneToMany(targetEntity="Configuration", mappedBy="object")
*/
private $configurations
//...
public function getConfigurationsWithName()
{
$subResult = new ArrayCollection();
foreach ($this->configurations as $configuration) {
if ($configuration->getName() != null) {
$subResult.add($configuration);
}
}
return $subResult;
}
//...
}
Then in twig
{% for filteredObject in object.configurationsWithName %}
...
{% endfor %}
So, the framework look for any getConfigurationsWithName inside the entity and find the new function. I hope this is what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With