acf-builder
acf-builder copied to clipboard
Instantiation in GroupBuilder constructor
https://github.com/StoutLogic/acf-builder/blob/68e3705505bc85b2d75e8e8d7fbb31181004b4cb/src/GroupBuilder.php#L25
In the mentioned line above, instantiation of a new FieldsBuilder in the GroupBuilder constructor is made.
The problem with this implementation is that it doesn't allow for dependency injection.
The reason dependency injection is needed here is in the case of extending FieldsBuilder
.
When I create a new class extending FieldsBuilder
lets call it FieldsBuilderChild
, calling addRepeater()
on FieldsBuilderChild
, would make the created repeater reference the parent FieldsBuilder
as the parent context, in which there were no repeater created, so when eventually endRepeater()
function is called, the function would not exist.
Here's a complete example:
use StoutLogic\AcfBuilder\FieldsBuilder;
class FieldsBuilderChild extends FieldsBuilder
{
private $titleField;
public function addTitleField()
{
$this->titleField = $this->addText('title');
}
}
now when building fields using FieldsBuilderChild
$fields = new FieldsBuilderChild();
$fields->addRepeater('Titles Repeater')
$fields->addTitleField();
$fields->endRepeater();
the following error would be thrown
Fatal error: Uncaught Exception: No such function: endRepeater in .../vendor/stoutlogic/acf-builder/src/ParentDelegationBuilder.php on line 69
For now, to fix this error in my application, I extended both GroupBiulder
and RepeaterBuilder
, overriding parent context setting, and overridden both addGroup()
and addRepeater
functions in my child FieldsBuilderChild
as follows:
-- GroupBuilder
<?php
namespace Fields;
use StoutLogic\AcfBuilder\GroupBuilder as BaseGroupBuilder;
class GroupBuilder extends BaseGroupBuilder
{
public function __construct($name, FieldsBuilder $builder, $type = 'group', $config = [])
{
parent::__construct($name, $type, $config);
$this->fieldsBuilder = $builder;
$this->fieldsBuilder->setParentContext($this);
}
}
-- RepeaterBuilder
<?php
namespace Fields;
use StoutLogic\AcfBuilder\RepeaterBuilder as BaseRepeaterBuilder;
class RepeaterBuilder extends BaseRepeaterBuilder
{
public function __construct($name, FieldsBuilder $builder, $type = 'group', $config = [])
{
parent::__construct($name, $type, $config);
$this->fieldsBuilder = $builder;
$this->fieldsBuilder->setParentContext($this);
}
}
-- FieldsBuilder
<?php
namespace Fields;
use StoutLogic\AcfBuilder\FieldsBuilder as BaseFieldsBuilder;
class FieldsBuilder extends BaseFieldsBuilder
{
private $titleField;
public function addGroup($name, array $args = [])
{
// overriding the parent addGroup to use the custom GroupBuilder
return $this->initializeField(new GroupBuilder($name, new self('group'), 'group', $args));
}
public function addRepeater($name, array $args = [])
{
// overriding the parent addRepeater to use the custom RepeaterBuilder
return $this->initializeField(new RepeaterBuilder($name, new self('repeater'), 'repeater', $args));
}
public function addTitleField()
{
$this->titleField = $this->addText('title');
}
}
Now the fatal error is no longer thrown, and fields are built correctly.
So, although this solution worked for me, but I think it's rather be implemented in the FieldsBuilder, and if this proposed solution is fine, I could add it and create a pull request.