In ZF2, I have 2 helpers. A helper has a form, and a mapper to handle the database interaction. I pass these helpers to the controller using a controller factory. The controller handles phones and addresses of a party that is either a person or an organization. Because a party is a person or an organization, it has different data, so the controller factory also passes the object: PersonObject or OrganizationObject with the party-specific data into the controller.
The 2 helpers are the same for both party types. But in the view script, I want to show the party-specific data, and here is my problem: I need to change the view script based on the object that the controller factory passes to the controller. I thought of having two different controllers, but it's an overkill: the view script is 90% the same, except for that 10% party-specific info that comes from the database into the party object.
How to change the view script from the controller factory? By changing here, I mean slightly different html layout with the party specific data.
EDIT:
@Saeven suggested posting some code. At the moment, I decided to create ViewModel
in the controller factory, prepare it accordingly, and inject it into the controller. But I'm not sure it's a good.
The Helper:
class ContactMechanismRegistrationViewHelper extends AbstractRegistrationViewHelper
{
public function __construct(
FormInterface $form,
ContactMechanismMapperInterface $contactMechanismMapper
) {
$this->form = $form;
$this->mapper = $contactMechanismMapper;
}
public function saveToDb()
{
$this->mapper->save(
$this->form->get('contactMechanismFieldset')->getObject(),
$this->form->get('partyFieldset')->getObject()
);
}
}
The helper factory:
class ContactMechanismRegistrationViewHelperFactory implements FactoryInterface, MutableCreationOptionsInterface
{
use MutableCreationOptionsTrait;
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
if (in_array('phone', $this->creationOptions)) {
return new ContactMechanismRegistrationViewHelper(
$formElementManager
->get('Parties\Forms\Forms\ContactMechanisms\PhoneRegistrationForm'),
$serviceManager
->get('Parties\Mappers\ContactMechanisms\PhoneMapper')
);
} elseif (in_array('address', $this->creationOptions)) {
return new ContactMechanismRegistrationViewHelper(
$formElementManager
->get('Parties\Forms\Forms\ContactMechanisms\AddressRegistrationForm'),
$serviceManager
->get('Parties\Mappers\ContactMechanisms\AddressMapper')
);
} else {
throw new ServiceNotCreatedException('wrong option type specified');
}
}
}
Controller that uses the helper:
class PartyDetailsController extends AbstractActionController
{
protected $phoneViewHelper;
protected $addressViewHelper;
protected $partyViewModel;
public function __construct(
ContactMechanismRegistrationViewHelper $phoneViewHelper,
ContactMechanismRegistrationViewHelper $addressViewHelper,
ModelInterface $viewModel
)
{
$this->phoneViewHelper = $phoneViewHelper;
$this->addressViewHelper = $addressViewHelper;
$this->viewModel = $viewModel;
}
public function indexAction()
{
$request = $this->getRequest();
if ($request->isPost()) {
$viewHelperForFormSubmission = $this->getViewHelperForFormSubmission(
$request->getPost('submitButton')
);
$viewHelperForFormSubmission->getForm()->setData($request->getPost());
$viewHelperForFormSubmission->getForm()->setIsSubmitted(true);
if ($viewHelperForFormSubmission->getForm()->isValid()) {
try {
$viewHelperForFormSubmission->saveToDb();
$viewHelperForFormSubmission->getForm()->resetForm();
} catch (\Exception $e) {
die($e->getMessage());
}
} else {
$viewHelperForFormSubmission->getForm()->highlightInvalidElements();
}
}
return $this->viewModel->setVariables([
'phoneForm' => $this->phoneViewHelper->getForm(),
'addressForm' => $this->addressViewHelper->getForm(),
]);
}
protected function getViewHelperForFormSubmission($submitValue)
{
if ($submitValue == 'phone') {
return $this->phoneViewHelper;
} elseif ($submitValue == 'address') {
return $this->addressViewHelper;
} else {
throw new \Exception('invalid submit argument');
}
}
}