mirror of
https://github.com/jbcr/core.git
synced 2026-04-29 03:33:24 +02:00
Merge pull request #787 from bolt/feature/collections-support-all-fields
Feature/collections support all fields
This commit is contained in:
@@ -4,16 +4,23 @@
|
||||
<div :is="element"></div>
|
||||
</div>
|
||||
|
||||
<editor-select
|
||||
ref="templateSelect"
|
||||
:value="initialSelectValue"
|
||||
:name="templateSelectName"
|
||||
:options="templateSelectOptions"
|
||||
:allowempty="false"
|
||||
></editor-select>
|
||||
<button class="btn btn-secondary" type="button" @click="addCollectionItem">
|
||||
{{ labels.add_collection_item }}
|
||||
</button>
|
||||
<div class="d-flex">
|
||||
<editor-select
|
||||
ref="templateSelect"
|
||||
class="flex-grow-1 mr-2"
|
||||
:value="initialSelectValue"
|
||||
:name="templateSelectName"
|
||||
:options="templateSelectOptions"
|
||||
:allowempty="false"
|
||||
></editor-select>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
type="button"
|
||||
@click="addCollectionItem"
|
||||
>
|
||||
{{ labels.add_collection_item }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -298,16 +298,35 @@ class ContentEditController extends TwigAwareController implements BackendZone
|
||||
|
||||
if (isset($formData['collections'])) {
|
||||
foreach ($formData['collections'] as $collection => $collectionItems) {
|
||||
$setsInCollection = [];
|
||||
$fieldsInCollection = [];
|
||||
$orderArray = array_flip($collectionItems['order']);
|
||||
|
||||
//update all fields of the collection and collect their field_name and field_reference
|
||||
foreach ($collectionItems as $collectionItemName => $collectionItemValue) {
|
||||
$setDefinition = $content->getDefinition()->get('fields')->get($collection)->get('fields')->get($collectionItemName);
|
||||
foreach ($collectionItemValue as $hash => $set) {
|
||||
$this->updateSet($content, $setDefinition, $hash, $set, $locale);
|
||||
$setsInCollection[] = [
|
||||
if ($collectionItemName === 'order') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$collectionItemDefinition = $content->getDefinition()->get('fields')->get($collection)->get('fields')->get($collectionItemName);
|
||||
if ($collectionItemDefinition['type'] === 'set') {
|
||||
// if this is a set field, create fields for each field within the set
|
||||
foreach ($collectionItemValue as $hash => $fieldValue) {
|
||||
$this->updateSet($content, $collectionItemDefinition, $hash, $fieldValue, $locale);
|
||||
}
|
||||
} else {
|
||||
// if this is any other field
|
||||
$field = $this->getFieldToUpdate($content, $collectionItemName, $collectionItemDefinition);
|
||||
$this->updateField($field, $collectionItemValue, $locale);
|
||||
}
|
||||
|
||||
//iterate over all submitted fields within the collection, get the correct index/order, to persist references
|
||||
//in the collection value
|
||||
foreach ($collectionItemValue as $hash => $fieldValue) {
|
||||
$index = $orderArray[$hash];
|
||||
$fieldsInCollection[$index] = [
|
||||
'field_name' => $collectionItemName,
|
||||
'field_reference' => $hash,
|
||||
'field_type' => $collectionItemDefinition['type'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -319,9 +338,11 @@ class ContentEditController extends TwigAwareController implements BackendZone
|
||||
$collectionField = Field::factory($content->getDefinition()->get('fields')->get($collection));
|
||||
}
|
||||
|
||||
//fill in the collection field value with the collected field_name and field_reference
|
||||
//sort the array keys (1,3,2) ascending (1,2,3)
|
||||
ksort($fieldsInCollection);
|
||||
|
||||
$collectionField->setName($collection);
|
||||
$collectionField->setValue($setsInCollection);
|
||||
$collectionField->setValue($fieldsInCollection);
|
||||
|
||||
if (! $content->hasField($collectionField->getName())) {
|
||||
$content->addField($collectionField);
|
||||
@@ -363,11 +384,13 @@ class ContentEditController extends TwigAwareController implements BackendZone
|
||||
}
|
||||
}
|
||||
|
||||
private function getFieldToUpdate(Content $content, string $fieldName): Field
|
||||
private function getFieldToUpdate(Content $content, string $fieldName, $fieldDefinition = ''): Field
|
||||
{
|
||||
/** @var Field $field */
|
||||
$field = null;
|
||||
|
||||
$definition = empty($fieldDefinition) ? $content->getDefinition()->get('fields')->get($fieldName) : $fieldDefinition;
|
||||
|
||||
if ($content->hasField($fieldName)) {
|
||||
$field = $content->getField($fieldName);
|
||||
}
|
||||
@@ -382,8 +405,7 @@ class ContentEditController extends TwigAwareController implements BackendZone
|
||||
|
||||
// Perhaps create a new Field..
|
||||
if (! $field) {
|
||||
$fields = $content->getDefinition()->get('fields');
|
||||
$field = Field::factory($fields->get($fieldName), $fieldName);
|
||||
$field = Field::factory($definition, $fieldName);
|
||||
|
||||
$field->setName($fieldName);
|
||||
$content->addField($field);
|
||||
|
||||
@@ -32,11 +32,21 @@ class CollectionField extends Field implements FieldInterface
|
||||
|
||||
$i = 0;
|
||||
foreach ($thisFieldValues as $thisFieldValue) {
|
||||
$field = new SetField();
|
||||
$field->setContent($this->getContent());
|
||||
$field->setValue($thisFieldValue['field_reference']);
|
||||
$field->setDefinition('fields', $this->getDefinition()->get('fields')[$thisFieldValue['field_name']]);
|
||||
$field->setName($thisFieldValue['field_name']);
|
||||
if ($thisFieldValue['field_type'] === 'set') {
|
||||
$field = new SetField();
|
||||
$field->setContent($this->getContent());
|
||||
$field->setValue($thisFieldValue['field_reference']);
|
||||
$field->setDefinition($thisFieldValue['field_name'], $this->getDefinition()->get('fields')[$thisFieldValue['field_name']]);
|
||||
$field->setName($thisFieldValue['field_name']);
|
||||
} else {
|
||||
$field = $this->getContent()->getField($thisFieldValue['field_name']);
|
||||
// The field value persists ALL the values for the same type collection items (e.g. all 'ages') in an array
|
||||
// To display the value for the current item, we set the value for the specific key only
|
||||
// As $this->getValue() is called multiple times, clone the object to ensure $field->setValue() is called once per instance
|
||||
$field = clone $field;
|
||||
$field->setValue($field->getValue()[$thisFieldValue['field_reference']]);
|
||||
$field->setDefinition($thisFieldValue['field_name'], $this->getDefinition()->get('fields')[$thisFieldValue['field_name']]);
|
||||
}
|
||||
|
||||
$result['fields'][$i] = $field;
|
||||
$i++;
|
||||
@@ -44,6 +54,7 @@ class CollectionField extends Field implements FieldInterface
|
||||
|
||||
foreach ($fieldDefinitions as $fieldName => $fieldDefinition) {
|
||||
$templateField = parent::factory($fieldDefinition, '', $fieldName);
|
||||
$templateField->setDefinition($fieldName, $this->getDefinition()->get('fields')[$fieldName]);
|
||||
$templateField->setName($fieldName);
|
||||
$result['templates'][$fieldName] = $templateField;
|
||||
}
|
||||
|
||||
@@ -36,3 +36,26 @@
|
||||
</a>
|
||||
|
||||
{% endapply %}{% endmacro %}
|
||||
|
||||
{% macro generate_collection_fields(collectionField, fields) %}{% apply spaceless %}
|
||||
{% set fieldsHtml = [] %}
|
||||
{% for item_field in fields %}
|
||||
{% set collectionItemName = 'collections[' ~ collectionField.name ~ '][' ~ item_field.definition.name ~ ']' %}
|
||||
{% if item_field.definition.type == 'set' %}
|
||||
{% set hash = item_field.hash %}
|
||||
{% else %}
|
||||
{# non-set fields do not have hashes, so we create a 'dummy' hash from the current loop index. #}
|
||||
{% set hash = loop.index0 %}
|
||||
{% set collectionItemName = collectionItemName ~ '[' ~ hash ~ ']' %}
|
||||
{% endif %}
|
||||
|
||||
{% set new_field %}
|
||||
{% include '@bolt/_partials/fields/' ~ item_field.type ~ '.html.twig' with
|
||||
{'field': item_field, 'in_collection': true, 'is_first': loop.index0 == 0, 'is_last': loop.index == fields|length, 'name': collectionItemName, 'collection_name': collectionField.name, 'hash': hash } only %}
|
||||
{% endset %}
|
||||
{# set the label manually as set in _base.html.twig, to pass to Collection.vue for templates #}
|
||||
{% set label = item_field.definition.label|default(item_field.name|default('unnamed')|ucwords) %}
|
||||
{% set fieldsHtml = fieldsHtml|merge([{'html': new_field, 'hash': hash, 'label': label}]) %}
|
||||
{% endfor %}
|
||||
{{ fieldsHtml|json_encode }}
|
||||
{% endapply %}{% endmacro %}
|
||||
|
||||
@@ -96,5 +96,24 @@
|
||||
{% block field %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{{ postfix|raw }}
|
||||
|
||||
{% if in_collection is defined %}
|
||||
<input type="hidden" name="collections[{{ collection_name }}][order][]" value="{{ hash }}">
|
||||
|
||||
<button class='action-move-up-collection-item btn btn-secondary' {% if is_first is defined and is_first %} disabled {% endif %}>
|
||||
<i class="fas fa-fw fa-chevron-up"></i>
|
||||
{{ 'collection.move_item_up'|trans }}
|
||||
</button>
|
||||
<button class='action-move-down-collection-item btn btn-secondary' {% if is_last is defined and is_last %} disabled {% endif %}>
|
||||
<i class="fas fa-fw fa-chevron-down"></i>
|
||||
{{ 'collection.move_item_down'|trans }}
|
||||
</button>
|
||||
<button class='action-remove-collection-item btn btn-hidden-danger'>
|
||||
<i class="fas fa-fw fa-times"></i>
|
||||
{{ 'collection.remove_item'|trans }}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends '@bolt/_partials/fields/_base.html.twig' %}
|
||||
{% import '@bolt/_macro/_macro.html.twig' as macro %}
|
||||
|
||||
{% block field %}
|
||||
{% set labels = {
|
||||
@@ -6,31 +7,20 @@
|
||||
} %}
|
||||
|
||||
{# get the html for all collection field already in the database #}
|
||||
{% set existing_fields = [] %}
|
||||
{% set existing_fields = "" %}
|
||||
{% if field.value.fields is defined %}
|
||||
{% for item_field in field.value.fields %}
|
||||
{% set collectionItemName = 'collections[' ~ field.name ~ '][' ~ item_field.name ~ ']' %}
|
||||
{% set existing_field %}
|
||||
{% include '@bolt/_partials/fields/' ~ item_field.type ~ '.html.twig' with
|
||||
{'field': item_field, 'in_collection': true, 'is_first': loop.index0 == 0, 'is_last': loop.index == field.value.fields|length, 'name': collectionItemName } only %}
|
||||
{% endset %}
|
||||
{% set existing_fields = existing_fields|merge([{'html': existing_field, 'hash': item_field.hash}]) %}
|
||||
{% endfor %}
|
||||
{% set existing_fields %}{{ macro.generate_collection_fields(field, field.value.fields) }}{% endset %}
|
||||
{% endif %}
|
||||
|
||||
{# get the html template for the collection fields defined in the field definition #}
|
||||
{% set templated_fields = [] %}
|
||||
{% for item_field in field.value.templates %}
|
||||
{% set collectionItemName = 'collections[' ~ field.name ~ '][' ~ item_field.name ~ ']' %}
|
||||
{% set templated_field %}
|
||||
{% include '@bolt/_partials/fields/' ~ item_field.type ~ '.html.twig' with {'field': item_field, 'in_collection': true, 'name': collectionItemName} only %}
|
||||
{% endset %}
|
||||
{% set templated_fields = templated_fields|merge([{'label': item_field.definition.label, 'html': templated_field, 'hash': item_field.hash}]) %}
|
||||
{% endfor %}
|
||||
{% set templated_fields = "" %}
|
||||
{% if field.value.templates is defined %}
|
||||
{% set templated_fields %}{{ macro.generate_collection_fields(field, field.value.templates) }}{% endset %}
|
||||
{% endif %}
|
||||
|
||||
<editor-collection
|
||||
:existing-fields='{{ existing_fields | json_encode }}'
|
||||
:templates='{{ templated_fields | json_encode }}'
|
||||
:existing-fields='{{ existing_fields }}'
|
||||
:templates='{{ templated_fields }}'
|
||||
:labels='{{ labels | json_encode }}'
|
||||
></editor-collection>
|
||||
|
||||
|
||||
@@ -11,19 +11,4 @@
|
||||
{% set setItemName = setName ~ '[' ~ field.value.hash ~ ']' ~ '[' ~ fieldItem.name ~ ']' %}
|
||||
{% include '@bolt/_partials/fields/' ~ fieldItem.type ~ '.html.twig' with {'field' : fieldItem, 'name' : setItemName} only %}
|
||||
{% endfor %}
|
||||
|
||||
{% if in_collection is defined %}
|
||||
<button class='action-move-up-collection-item btn btn-secondary' {% if is_first is defined and is_first %} disabled {% endif %}>
|
||||
<i class="fas fa-fw fa-chevron-up"></i>
|
||||
{{ 'collection.move_item_up'|trans }}
|
||||
</button>
|
||||
<button class='action-move-down-collection-item btn btn-secondary' {% if is_last is defined and is_last %} disabled {% endif %}>
|
||||
<i class="fas fa-fw fa-chevron-down"></i>
|
||||
{{ 'collection.move_item_down'|trans }}
|
||||
</button>
|
||||
<button class='action-remove-collection-item btn btn-hidden-danger'>
|
||||
<i class="fas fa-fw fa-times"></i>
|
||||
{{ 'collection.remove_item'|trans }}
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user