mirror of
https://github.com/jbcr/core.git
synced 2026-04-27 02:28:08 +02:00
Makes collections persist. Introduces FieldParentInterface and FieldParentTrait
This commit is contained in:
@@ -10,6 +10,7 @@ use Bolt\Controller\CsrfTrait;
|
||||
use Bolt\Controller\TwigAwareController;
|
||||
use Bolt\Entity\Content;
|
||||
use Bolt\Entity\Field;
|
||||
use Bolt\Entity\Field\CollectionField;
|
||||
use Bolt\Entity\Field\SetField;
|
||||
use Bolt\Entity\Relation;
|
||||
use Bolt\Entity\User;
|
||||
@@ -317,62 +318,44 @@ class ContentEditController extends TwigAwareController implements BackendZone
|
||||
}
|
||||
}
|
||||
|
||||
// if (isset($formData['collections'])) {
|
||||
// foreach ($formData['collections'] as $collection => $collectionItems) {
|
||||
// $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) {
|
||||
// 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) {
|
||||
// continue;
|
||||
//// $this->updateSetItems($content, $collectionItemDefinition, $hash, $fieldValue, $locale);
|
||||
// }
|
||||
// } else {
|
||||
// // if this is any other field
|
||||
// $fieldDBname = $collection . '::' . $collectionItemName;
|
||||
// $field = $this->getFieldToUpdate($content, $fieldDBname, $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'],
|
||||
//// ];
|
||||
//// }
|
||||
// }
|
||||
//
|
||||
// //create the collection field itself
|
||||
// if ($content->hasField($collection)) {
|
||||
// $collectionField = $content->getField($collection);
|
||||
// } else {
|
||||
// $collectionField = FieldRepository::factory($content->getDefinition()->get('fields')->get($collection));
|
||||
// }
|
||||
//
|
||||
// //sort the array keys (1,3,2) ascending (1,2,3)
|
||||
// ksort($fieldsInCollection);
|
||||
//
|
||||
// $collectionField->setName($collection);
|
||||
// $collectionField->setValue($fieldsInCollection);
|
||||
// $collectionField->setLocale($locale);
|
||||
//
|
||||
// if (! $content->hasField($collectionField->getName())) {
|
||||
// $content->addField($collectionField);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (isset($formData['collections'])) {
|
||||
foreach ($formData['collections'] as $collectionName => $collectionItems) {
|
||||
$collectionDefinition = $content->getDefinition()->get('fields')->get($collectionName);
|
||||
$orderArray = array_flip($collectionItems['order']);
|
||||
|
||||
if ($content->hasField($collectionName)) {
|
||||
/** @var CollectionField $collection */
|
||||
$collection = $content->getField($collectionName);
|
||||
} else {
|
||||
/** @var CollectionField $collection */
|
||||
$collection = Field::factory($collectionDefinition, $collectionName);
|
||||
$collection->setLocale($locale);
|
||||
$content->addField($collection);
|
||||
}
|
||||
|
||||
foreach ($collectionItems as $name => $collectionItemValue) {
|
||||
// order field is only used to determine the order in which fields are submitted
|
||||
if ($name === 'order') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hash = array_key_first($collectionItemValue);
|
||||
$value = $collectionItemValue[$hash];
|
||||
$order = $orderArray[$hash];
|
||||
|
||||
if($collection->hasChild($name)) {
|
||||
$field = $collection->getChild($name);
|
||||
} else {
|
||||
$field = Field::factory($collectionDefinition->get('fields')->get($name), $name);
|
||||
$field->setParent($collection);
|
||||
$field->setSortorder($order);
|
||||
$content->addField($field);
|
||||
}
|
||||
|
||||
$this->updateField($field, $value, $locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($formData['taxonomy'])) {
|
||||
foreach ($formData['taxonomy'] as $fieldName => $taxonomy) {
|
||||
|
||||
@@ -6,53 +6,31 @@ namespace Bolt\Entity\Field;
|
||||
|
||||
use Bolt\Entity\Field;
|
||||
use Bolt\Entity\FieldInterface;
|
||||
use Bolt\Repository\FieldRepository;
|
||||
use Bolt\Entity\FieldParentInterface;
|
||||
use Bolt\Entity\FieldParentTrait;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Sirius\Upload\Util\Arr;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class CollectionField extends Field implements FieldInterface
|
||||
class CollectionField extends Field implements FieldInterface, FieldParentInterface
|
||||
{
|
||||
use FieldParentTrait;
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return 'collection';
|
||||
}
|
||||
|
||||
private function getCollectionFieldValues(): array
|
||||
{
|
||||
return parent::getValue();
|
||||
}
|
||||
|
||||
public function getValue(): array
|
||||
{
|
||||
$fieldDefinitions = $this->getDefinition()->get('fields', []);
|
||||
$result = [];
|
||||
|
||||
$thisFieldValues = $this->getCollectionFieldValues();
|
||||
|
||||
$i = 0;
|
||||
foreach ($thisFieldValues as $thisFieldValue) {
|
||||
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 {
|
||||
$fieldDBname = $this->getName() . '::' . $thisFieldValue['field_name'];
|
||||
$field = $this->getContent()->getField($fieldDBname);
|
||||
//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->setName($thisFieldValue['field_name']);
|
||||
$field->setValue($field->getValue()[$thisFieldValue['field_reference']]);
|
||||
$field->setDefinition($thisFieldValue['field_name'], $this->getDefinition()->get('fields')[$thisFieldValue['field_name']]);
|
||||
}
|
||||
$result['fields'][$i] = $field;
|
||||
$i++;
|
||||
}
|
||||
$result['fields'] = $this->getOrderedChildren();
|
||||
|
||||
foreach ($fieldDefinitions as $fieldName => $fieldDefinition) {
|
||||
$templateField = FieldRepository::factory($fieldDefinition, '', $fieldName);
|
||||
@@ -63,4 +41,24 @@ class CollectionField extends Field implements FieldInterface
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getOrderedChildren(): ArrayCollection
|
||||
{
|
||||
if(! $this->getContent())
|
||||
{
|
||||
return new ArrayCollection();
|
||||
}
|
||||
|
||||
$query = $this->getContent()->getRawFields()->filter(function (Field $field) {
|
||||
return $field->getParent() === $this;
|
||||
});
|
||||
|
||||
$iterator = $query->getIterator();
|
||||
|
||||
$iterator->uasort(function (Field $first, Field $second){
|
||||
return (int) $first->getSortorder() > (int) $second->getSortorder() ? 1 : -1;
|
||||
});
|
||||
|
||||
return new ArrayCollection(iterator_to_array($iterator));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,17 @@ namespace Bolt\Entity\Field;
|
||||
|
||||
use Bolt\Entity\Field;
|
||||
use Bolt\Entity\FieldInterface;
|
||||
use Bolt\Repository\FieldRepository;
|
||||
use Bolt\Entity\FieldParentInterface;
|
||||
use Bolt\Entity\FieldParentTrait;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class SetField extends Field implements FieldInterface
|
||||
class SetField extends Field implements FieldInterface, FieldParentInterface
|
||||
{
|
||||
use FieldParentTrait;
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return 'set';
|
||||
@@ -44,20 +47,4 @@ class SetField extends Field implements FieldInterface
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getChild(string $fieldName): Field
|
||||
{
|
||||
return $this->getContent()->getRawFields()->filter(function (Field $field) use ($fieldName) {
|
||||
return $field->getParent() === $this && $field->getName() === $fieldName;
|
||||
})->first();
|
||||
}
|
||||
|
||||
public function hasChild(string $fieldName): bool
|
||||
{
|
||||
$query = $this->getContent()->getRawFields()->filter(function (Field $field) use ($fieldName) {
|
||||
return $field->getParent() === $this && $field->getName() === $fieldName;
|
||||
});
|
||||
|
||||
return ! $query->isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Bolt\Entity;
|
||||
|
||||
/**
|
||||
* Any Field entity that has child fields must implement this interface.
|
||||
*/
|
||||
interface FieldParentInterface
|
||||
{
|
||||
public function getChild(string $fieldName): Field;
|
||||
|
||||
public function hasChild(string $fieldName): bool;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Bolt\Entity;
|
||||
|
||||
/**
|
||||
* Implements the methods of the FieldParentInterface.
|
||||
*/
|
||||
trait FieldParentTrait
|
||||
{
|
||||
abstract public function getContent(): ?Content;
|
||||
|
||||
public function getChild(string $fieldName): Field
|
||||
{
|
||||
return $this->getContent()->getRawFields()->filter(function (Field $field) use ($fieldName) {
|
||||
return $field->getParent() === $this && $field->getName() === $fieldName;
|
||||
})->first();
|
||||
}
|
||||
|
||||
public function hasChild(string $fieldName): bool
|
||||
{
|
||||
$query = $this->getContent()->getRawFields()->filter(function (Field $field) use ($fieldName) {
|
||||
return $field->getParent() === $this && $field->getName() === $fieldName;
|
||||
});
|
||||
|
||||
return ! $query->isEmpty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user