Using Symfony, I am displaying a table with some entries the user is able to select from. There is a little more complexity as this might include calling some further actions e. g. for filtering the table entries, sorting by different criteria, etc.
I have implemented the whole thing in an own bundle, let's say ChoiceTableBundle
(with ChoiceTableController
). Now I would like to be able to use this bundle from other bundles, sometimes with some more parametrization.
My desired workflow would then look like this:
OtherBundle
and triggers chooseAction
.chooseAction
forwards to ChoiceTableController
(resp. its default entry action).ChoiceTableBundle
, the user is able to navigate, filter, sort, ... using the actions and routing supplied by this bundle.choiceFinishedAction
) and the control flow returns to OtherBundle
, handing over the results of the users choice.OtherBundle
can then continue working.Additionally, OtherOtherBundle
(and some more...) should also be able to use this workflow, possibly passing some configuration values to ChoiceTableBundle
to make it behave a little different.
I have read about the "Controller as Service" pattern of Symfony 2 and IMHO it's the right approach here (if not, please tell me ;)). So I would make a service out of ChoiceTableController
and use it from the other bundles. Anyway, with the workflow above in mind, I don't see a "good" way to achieve this:
ChoiceTableBundle
(resp. ChoiceTableController
), if neccessary?ChoiceTableBundle
know from where it was called?Basic approaches could be to store the values in the session or to create an intermediate object being passed. Both do not seem particularly elegant to me. Can you please give me a shove in the right direction? Many thanks in advance!
The main question is if you really need to call your filtering / searching logic as a controller action. Do you really need to make a request?
I would say it could be also doable just by passing all the required data to a service you define.
This service you should create from the guts of your ChoiceTableBundle
and let both you ChoiceTableBundle
and your OtherBundle
to use the extracted service.
// register it in your service container
class FilteredDataProvider
{
/**
* @return customObjectInterface or scallar or whatever you like
*/
public function doFiltering($searchString, $order)
{
return $this->filterAndReturnData($searchString, $order)
}
}
...
class OtherBundleController extends Controller {
public function showStuffAction() {
$result = $this->container->get('filter_data_provider')
->doFiltering('text', 'ascending')
}
}
The whole thing can be accomplished with the same approach as lipp/imagine bundle uses.
Have a controller as service and call/send all the required information to that controller when you need some results, you can also send whole request.
class MyController extends Controller
{
public function indexAction()
{
// RedirectResponse object
$responeFromYourSearchFilterAction = $this->container
->get('my_search_filter_controller')
->filterSearchAction(
$this->request, // http request
'parameter1' // like search string
'parameterX' // like sorting direction
);
// do something with the response
// ..
}
}
A separate service class would be much more flexible. Also if you need other parameters or Request object you can always provide it.
Info how to declare controller as service is here: http://symfony.com/doc/current/cookbook/controller/service.html
How liip uses it: https://github.com/liip/LiipImagineBundle#using-the-controller-as-a-service