-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adjust dump method in Extended\ACF\Fields\Field to utilize object cloning #154
base: master
Are you sure you want to change the base?
Conversation
Thanks for the pull request. This approach may not work as we create field keys on the fly. If the keys are generated without a parent, they could become invalid. Is there a way to clone the field within the |
That would only be symptom control. I actually stumbeled across this bug when I was trying to use the get method itself. So if we would adjust the dump() method, the problem would still occure if someone would use the get() method. Here is a code snippet of how I want to utilize the get() method: private function registerOptionPageContext(array $option_page): void
{
if (!isset($option_page['page_settings']['timber_context_key'])) {
return;
}
add_filter('timber/context', function ($context) use ($option_page) {
$context[$option_page['page_settings']['timber_context_key']] = $this->getFieldsContext($option_page);
return $context;
});
}
private function getFieldsContext(array $option_page): array
{
$fieldsContext = [];
$fields = $option_page['acf_settings']['fields'] ?? [];
foreach ($fields as $field) {
$key = $field->get()['key'];
$name = $field->get()['name'];
$fieldsContext[$name] = get_field($key, 'option');
}
return $fieldsContext;
} With those two methods I am looping through all the fields registered in option pages and and adding them to the timber contect, to make them available in the frontend. I am using the get() method to get the field key, so i can use the get_field() function. This all needs to work dynamically since extended-acf generates the keys on the fly. |
The
I'm curious. Why aren't the fields available by default in Timber? |
That's a very good question. I've never questioned this, since it has always been like this in the theme since I work here. I checked the Timber Docs and they recommend to use As for this PR: I think it would still be better to find a solution for fields that utilize child fields. As of now, even if you don't use the get() method, as you suggested, the dump() method is broken for fields with subfields. So I would either prevent the usage of dump() on those fields or maybe trying to find a solution for this. I'm not that familiar with the codebase of this repo or the acf source code. But could something like this be a solution? /** @internal */
public function get(string|null $parentKey = null): array
{
// Resolve the parent key to ensure it's valid within the current context
$resolvedParentKey = $parentKey !== null ? Key::resolveParentKey($parentKey, $this->settings['name']) : null;
$key =
$this->settings['key'] ??
($resolvedParentKey !== null ? $resolvedParentKey . '_' : '') . Key::sanitize($this->settings['name']);
if ($this->type !== null) {
$this->settings['type'] = $this->type;
}
if (isset($this->settings['conditional_logic'])) {
$this->settings['conditional_logic'] = array_map(
fn($rules) => is_object($rules) && method_exists($rules, 'get')
? $rules->get($resolvedParentKey)
: $rules,
$this->settings['conditional_logic'],
);
}
if (isset($this->settings['layouts'])) {
$this->settings['layouts'] = array_map(
fn($layout) => is_object($layout) && method_exists($layout, 'get')
? $layout->get($key)
: $layout,
$this->settings['layouts'],
);
}
if (isset($this->settings['sub_fields'])) {
$this->settings['sub_fields'] = array_map(
fn($field) => is_object($field) && method_exists($field, 'get')
? $field->get($key)
: $field,
$this->settings['sub_fields'],
);
}
if (isset($this->settings['collapsed'], $this->settings['sub_fields'])) {
foreach ($this->settings['sub_fields'] as $field) {
if (is_array($field) && isset($field['name']) && $field['name'] === $this->settings['collapsed']) {
$this->settings['collapsed'] = $field['key'] ?? $this->settings['collapsed'];
break;
}
}
}
$this->settings['key'] ??= Key::generate($key, $this->keyPrefix);
return $this->settings;
} |
I may be mistaken, but this could also pose a problem since we require the field group key to generate the initial parent key. Is there a way to resolve this using only the |
…ect cloning" This reverts commit b52e69a.
I think cloning the object before getting the settings is the most straightforward solution. Returning the Field after calling |
Thank you for the update. Have you tried this approach? The error still seems to be occurring on my end. |
@vinkla It does work on my end. 🤔 |
I know why I still see the error on my side. It's because I have nested repeaters. We might need to map over the fields first and clone them if they have subfields. |
@vinkla The fields should now be cloned recursively. |
Do you need me to do anything else? |
Sorry for the delay, haven't had time to look into this. Will look at it in the future. |
This PR will fix #153.
Description
This pull request refactors the get method in the Extended\ACF\Fields\Field class to utilize PHP object cloning. The changes ensure that field instances, particularly those with sub_fields, layouts, and conditional_logic, are processed independently, preventing unintended modifications to the original objects during method execution.
Changes Made