![]() |
|
Snippets |
|
By default, the admin generator allows to filter the data with the rows from the table currently listed.
Here's how to extend this to data from other linked tables.
We'll consider the following example : a table "command" linked to a table "user". This very simple schema.xml shows the relation between these two tables :
<table name="buyer" phpName="BtqBuyer" > <column name="buyer_id" type="BIGINT" required="true" primaryKey="true"/> <column name="buyer_name" type="VARCHAR" size="255" required="true"/> </table> <table name="command" phpName="BtqCommand" > <column name="com_id" type="BIGINT" required="true" primaryKey="true"/> <column name="com_ref" type="VARCHAR" size="6" required="true"/> <column name="com_buyer_id" type="BIGINT" required="true"/> <foreign-key foreignTable="buyer" onDelete="" onUpdate=""> <reference local="com_buyer_id" foreign="buyer_id"/> </foreign-key> </table>
In the file generator.yml, add a partial in the filters parameter to print our specific filter :
filters: [com_ref, _btq_buyer]
The source code for the partial _btq_buyer.php (located in the templates directory) is :
<?php echo input_tag('filters[buyer]', isset($filters['buyer']) ? $filters['buyer'] : '') ?>
Now we have to add our specific filter in the filter process. To do this, we extend the addFiltersCriteria from the admin generator. This is done in the file actions.class.php by adding :
protected function addFiltersCriteria (&$c) { if (isset($this->filters['buyer']) && $this->filters['buyer'] != '') { $c->add(BtqBuyerPeer::BUYER_NAME, strtr($this->filters['buyer'], '*', '%'), Criteria::LIKE); $c->addJoin(BtqBuyerPeer::BUYER_ID, BtqCommandPeer::COM_BUYER_ID); } }
As you can see, we've even allowed the use of wildcard in our filter. Nice ;)
Comments on this snippet
If you get this error: Strict Standards: Declaration of hostdetailActions::addFiltersCriteria() should be compatible with that of....
This is what I have found. I am not sure why author is passing the $c by refference (&).
Instead of: protected function addFiltersCriteria (&$c)
Use: protected function addFiltersCriteria ($c)
Also, it's good to add call to the parent addFiltersCriteria function, because otherwise, if you have more filters toggled, they will be not processed. So the function will look like this:
protected function addFiltersCriteria ($c) { if (isset($this->filters['buyer']) && $this->filters['buyer'] != '') { $c->add(BtqBuyerPeer::BUYER_NAME, strtr($this->filters['buyer'], '*', '%'), Criteria::LIKE); $c->addJoin(BtqBuyerPeer::BUYER_ID, BtqCommandPeer::COM_BUYER_ID); } parent::addFiltersCriteria($c); }
But I see one problem with this, that I am not sure how Symfony is solving. If you call the parent function, there are already rules for the filters[buyer] set and they will probably give you error, something like: Fatal error: Undefined class constant...
That's because the filters['buyer'] is set by the generator automaticaly, but with the bad Criteria definition. Even if you override the function and set new criteria, if you will call the parent function, the bad criteria are triggered and will give you this error.
Is the Symfony solution for this to redefine all the filters (even the standard ones) in the overriden function?
Hi neon,
I think you could unset $this->filters['buyer'] before calling parent::adFiltersCriteria, and your worries should be solved :)
Not tested, but I've seen
unset($this->filters['buyer']);
or similar code many times fiddling around symfony base code :)
Good luck!
Nice try, but:
This will also remove it from displaying again the filter...
This is a bit of a hack but it seems to do the trick. The idea is to store the custom filter value in a temp variable and clearing the filter while calling the autogenerated addFiltersCriteria() and restoring it after that.
$tmp=''; if (isset($this->filters['buyer']) && $this->filters['buyer'] != '') { // do stuff $tmp = $this->filters['buyer']; }
parent::addFiltersCriteria($c); $this->filters['buyer']=$tmp;