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