I'm building a CommerceManager
plugin to manage purchases for online shops.
CommerceManager
plugin sideTo deal with the billing/delivery step I have created a Modelless Form DeliveryForm
which is useful for :
// in plugin/CommerceManager/src/Form/DeliveryForm.php
class DeliveryForm extends Form
{
/**
* List of countries available used for <select> in delivery form
*
* @var array
*/
public $countries = [
'AL' => ['name' => 'ALBANIA', 'code' => '008'],
// [...]
'FR' => ['name' => 'FRANCE', 'code' => '250'],
// [...]
];
public function validationDefault(Validator $validator): Validator
{
// validates form data
}
public function read()
{
$session = Session::create();
return $session->read('Buyer') ?? [];
}
protected function _execute(array $data): bool
{
$session = Session::create();
$session->write('Buyer', $data);
return true;
}
}
My CommerceManager
plugin has a CheckoutController
which uses the plugin's DeliveryForm
:
// in plugin/CommerceManager/src/Controller/CheckoutController.php
use CommerceManager\Form\DeliveryForm; // use plugin's DeliveryForm
class CheckoutController extends AppController
{
public function delivery()
{
$deliveryForm = new DeliveryForm();
if ($this->request->is('post')) {
if ($deliveryForm->execute($this->request->getData())) {
return $this->redirect(['action' => 'confirm']);
}
}
else {
$deliveryForm->setData($deliveryForm->read() ?? []);
}
$this->set(compact('deliveryForm'));
}
// [...]
}
I would like to make a subclass of DeliveryForm
for overriding the list of countries available for delivery.
To do that I've created a subclass of CheckoutController
which only inherits the actions of its parent and uses App's DeliveryForm
.
// in src/Controller/CheckoutController.php
use CommerceManager\Controller\CheckoutController as BaseCheckoutController;
use App\Form\DeliveryForm; // use App's DeliveryForm
class CheckoutController extends BaseCheckoutController
{
// inherits actions of CommerceManager.CheckoutController
}
// in src/Form/DeliveryForm.php
use CommerceManager\Form\DeliveryForm as BaseDeliveryForm;
class DeliveryForm extends BaseDeliveryForm
{
public $countries = [
'FR' => ['name' => 'FRANCE', 'code' => '250'] // Only "France" is available
];
}
The problem comes from the fact that App still using CommerceManager
's DeliveryForm
.
I'm totally confused about how to deal with DeliveryForm
inheritance...
How can I do for my App's CheckoutController
could understand to use App's DeliveryForm
subclass and not the plugin's one ?
// in plugin/CommerceManager/src/Controller/CheckoutController.php
use CommerceManager\Form\DeliveryForm; // use plugin's DeliveryForm
class CheckoutController extends AppController
{
/**
* The class to instanciate
*/
protected $_classnameDeliveryForm = \CommerceManager\Form\DeliveryForm::class;
/**
* The instance
*/
protected $DeliveryForm;
public function initialize(): void
{
parent::initialize();
$this->DeliveryForm = new $this->_classnameDeliveryForm();
}
public function delivery()
{
if ($this->request->is('post')) {
if ($this->DeliveryForm->execute($this->request->getData())) {
return $this->redirect(['action' => 'confirm']);
}
}
else {
$this->DeliveryForm->setData($this->DeliveryForm->read() ?? []);
}
$this->set('deliveryForm', $this->DeliveryForm);
}
// [...]
}