2020-09-28 01:25:07 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Model\Table;
|
|
|
|
|
|
|
|
use App\Model\Table\AppTable;
|
|
|
|
use Cake\ORM\Table;
|
2021-12-08 11:11:46 +01:00
|
|
|
use Cake\ORM\TableRegistry;
|
2020-09-28 01:25:07 +02:00
|
|
|
use Cake\Validation\Validator;
|
2021-12-01 11:01:31 +01:00
|
|
|
use Cake\Utility\Hash;
|
2021-12-08 11:11:46 +01:00
|
|
|
use Cake\Utility\Inflector;
|
|
|
|
use Cake\Utility\Text;
|
2020-09-28 01:25:07 +02:00
|
|
|
|
|
|
|
class MetaTemplatesTable extends AppTable
|
|
|
|
{
|
2021-12-01 11:01:31 +01:00
|
|
|
public const TEMPLATE_PATH = [
|
|
|
|
ROOT . '/libraries/default/meta_fields/',
|
|
|
|
ROOT . '/libraries/custom/meta_fields/'
|
|
|
|
];
|
|
|
|
|
2020-09-28 01:25:07 +02:00
|
|
|
public function initialize(array $config): void
|
|
|
|
{
|
|
|
|
parent::initialize($config);
|
2021-09-28 13:32:51 +02:00
|
|
|
$this->addBehavior('Timestamp');
|
2020-09-28 01:25:07 +02:00
|
|
|
$this->hasMany(
|
|
|
|
'MetaTemplateFields',
|
|
|
|
[
|
2021-12-08 11:11:46 +01:00
|
|
|
'foreignKey' => 'meta_template_id',
|
|
|
|
'saveStrategy' => 'replace',
|
|
|
|
'dependent' => true,
|
|
|
|
'cascadeCallbacks' => true,
|
2020-09-28 01:25:07 +02:00
|
|
|
]
|
|
|
|
);
|
2021-09-09 13:12:52 +02:00
|
|
|
$this->setDisplayField('name');
|
2020-09-28 01:25:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function validationDefault(Validator $validator): Validator
|
|
|
|
{
|
|
|
|
$validator
|
|
|
|
->notEmptyString('scope')
|
|
|
|
->notEmptyString('name')
|
|
|
|
->notEmptyString('namespace')
|
|
|
|
->notEmptyString('uuid')
|
|
|
|
->notEmptyString('version')
|
|
|
|
->notEmptyString('source')
|
|
|
|
->requirePresence(['scope', 'source', 'version', 'uuid', 'name', 'namespace'], 'create');
|
|
|
|
return $validator;
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function update($template_uuid=null, $strategy=null)
|
2020-09-28 01:25:07 +02:00
|
|
|
{
|
|
|
|
$files_processed = [];
|
2021-12-01 11:01:31 +01:00
|
|
|
// foreach (self::TEMPLATE_PATH as $path) {
|
|
|
|
// if (is_dir($path)) {
|
|
|
|
// $files = scandir($path);
|
|
|
|
// foreach ($files as $k => $file) {
|
|
|
|
// if (substr($file, -5) === '.json') {
|
|
|
|
// if ($this->loadAndSaveMetaFile($path . $file) === true) {
|
|
|
|
// $files_processed[] = $file;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
$readErrors = [];
|
|
|
|
$preUpdateChecks = [];
|
|
|
|
$updatesErrors = [];
|
|
|
|
$templates = $this->readTemplatesFromDisk($readErrors);
|
|
|
|
foreach ($templates as $template) {
|
2021-12-08 11:11:46 +01:00
|
|
|
$updateStatus = $this->checkForUpdates($template['uuid']);
|
|
|
|
$preUpdateChecks[$template['uuid']] = $updateStatus;
|
|
|
|
if (is_null($template_uuid) || $template_uuid == $template['uuid']) {
|
|
|
|
$errors = [];
|
|
|
|
$success = false;
|
|
|
|
if ($updateStatus['up-to-date']) {
|
|
|
|
$errors['message'] = __('Meta-template already up-to-date');
|
|
|
|
$success = true;
|
|
|
|
} else if ($updateStatus['new']) {
|
|
|
|
$success = $this->saveNewMetaTemplate($template, $errors);
|
|
|
|
} else if ($updateStatus['updateable']) {
|
|
|
|
$success = $this->updateMetaTemplate($template, $errors);
|
|
|
|
} else if (!$updateStatus['up-to-date'] && is_null($strategy)) {
|
|
|
|
$errors['message'] = __('Cannot update meta-template, update strategy not provided');
|
|
|
|
} else if (!$updateStatus['up-to-date'] && !is_null($strategy)) {
|
|
|
|
$success = $this->updateMetaTemplateWithStrategy($template, $strategy, $errors);
|
|
|
|
} else {
|
|
|
|
$errors['message'] = __('Could not update. Something went wrong.');
|
|
|
|
}
|
|
|
|
if ($success) {
|
|
|
|
$files_processed[] = $template['uuid'];
|
|
|
|
}
|
|
|
|
if (!empty($errors)) {
|
|
|
|
$updatesErrors[] = $errors;
|
|
|
|
}
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
$results = [
|
2021-12-01 11:01:31 +01:00
|
|
|
'read_errors' => $readErrors,
|
|
|
|
'pre_update_errors' => $preUpdateChecks,
|
|
|
|
'update_errors' => $updatesErrors,
|
2021-12-08 11:11:46 +01:00
|
|
|
'files_processed' => $files_processed,
|
|
|
|
'success' => !empty($files_processed),
|
2021-12-01 11:01:31 +01:00
|
|
|
];
|
2021-12-08 11:11:46 +01:00
|
|
|
return $results;
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function checkForUpdates($template_uuid=null): array
|
2021-12-01 11:01:31 +01:00
|
|
|
{
|
|
|
|
$templates = $this->readTemplatesFromDisk($readErrors);
|
|
|
|
$result = [];
|
|
|
|
foreach ($templates as $template) {
|
2021-12-08 11:11:46 +01:00
|
|
|
if (is_null($template_uuid)) {
|
|
|
|
$result[$template['uuid']] = $this->checkUpdatesForTemplate($template);
|
|
|
|
} else if ($template['uuid'] == $template_uuid) {
|
|
|
|
$result = $this->checkUpdatesForTemplate($template);
|
|
|
|
return $result;
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function isUpToDate(array $updateResult): bool
|
|
|
|
{
|
|
|
|
return $updateResult['up-to-date'] || $updateResult['new'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function isUpdateable(array $updateResult): bool
|
|
|
|
{
|
|
|
|
return $updateResult['updateable'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function isNew(array $updateResult): bool
|
|
|
|
{
|
|
|
|
return $updateResult['new'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasNoConflict(array $updateResult): bool
|
|
|
|
{
|
|
|
|
return $this->hasConflict($updateResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasConflict(array $updateResult): bool
|
|
|
|
{
|
|
|
|
return !$updateResult['updateable'] && !$updateResult['up-to-date'] && !$updateResult['new'];
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function isUpdateableToExistingMetaTemplate($metaTemplate): bool
|
|
|
|
{
|
|
|
|
$newestTemplate = $this->getNewestVersion($metaTemplate);
|
|
|
|
return !empty($newestTemplate);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function isRemovable(array $updateResult): bool
|
|
|
|
{
|
|
|
|
return !empty($updateResult['can_be_removed']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getTemplateStatus(array $updateResult, $metaTemplate): array
|
2021-12-01 11:01:31 +01:00
|
|
|
{
|
|
|
|
return [
|
|
|
|
'up_to_date' => $this->isUpToDate($updateResult),
|
|
|
|
'updateable' => $this->isUpdateable($updateResult),
|
|
|
|
'is_new' => $this->isNew($updateResult),
|
|
|
|
'has_conflict' => $this->hasConflict($updateResult),
|
2021-12-08 11:11:46 +01:00
|
|
|
'to_existing' => $this->isUpdateableToExistingMetaTemplate($metaTemplate),
|
|
|
|
'can_be_removed' => $this->isRemovable($updateResult),
|
2021-12-01 11:01:31 +01:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getUpToDateTemplates($result=null): array
|
|
|
|
{
|
|
|
|
$result = is_null($result) ? $this->checkForUpdates() : $result;
|
|
|
|
foreach ($result as $i => $updateResult) {
|
|
|
|
if (!$this->isUpToDate($updateResult)) {
|
|
|
|
unset($result[$i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getNotUpToDateTemplates($result=null): array
|
|
|
|
{
|
|
|
|
$result = is_null($result) ? $this->checkForUpdates() : $result;
|
|
|
|
foreach ($result as $i => $updateResult) {
|
|
|
|
if ($this->isUpToDate($updateResult)) {
|
|
|
|
unset($result[$i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getUpdateableTemplates($result=null): array
|
|
|
|
{
|
|
|
|
$result = is_null($result) ? $this->checkForUpdates() : $result;
|
|
|
|
foreach ($result as $i => $updateResult) {
|
|
|
|
if (!$this->isUpdateable($updateResult)) {
|
|
|
|
unset($result[$i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getNewTemplates($result=null): array
|
|
|
|
{
|
|
|
|
$result = is_null($result) ? $this->checkForUpdates() : $result;
|
|
|
|
foreach ($result as $i => $updateResult) {
|
|
|
|
if (!$this->isNew($updateResult)) {
|
|
|
|
unset($result[$i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getConflictTemplates($result=null): array
|
|
|
|
{
|
|
|
|
$result = is_null($result) ? $this->checkForUpdates() : $result;
|
|
|
|
foreach ($result as $i => $updateResult) {
|
|
|
|
if (!$this->hasConflict($updateResult)) {
|
|
|
|
unset($result[$i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function getNewestVersion($metaTemplate, $full=false)
|
|
|
|
{
|
|
|
|
$query = $this->find()->where([
|
|
|
|
'uuid' => $metaTemplate->uuid,
|
|
|
|
'id !=' => $metaTemplate->id,
|
|
|
|
'version >=' => $metaTemplate->version,
|
|
|
|
])
|
|
|
|
->order(['version' => 'DESC']);
|
|
|
|
if ($full) {
|
|
|
|
$query->contain(['MetaTemplateFields']);
|
|
|
|
}
|
|
|
|
$newestTemplate = $query->first();
|
|
|
|
return $newestTemplate;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getCanBeRemovedTemplates($result=null): array
|
|
|
|
{
|
|
|
|
$result = is_null($result) ? $this->checkForUpdates() : $result;
|
|
|
|
foreach ($result as $i => $updateResult) {
|
|
|
|
if (!$this->isRemovable($updateResult)) {
|
|
|
|
unset($result[$i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2021-12-01 11:01:31 +01:00
|
|
|
public function readTemplatesFromDisk(&$errors=[]): array
|
|
|
|
{
|
|
|
|
$templates = [];
|
|
|
|
$errors = [];
|
|
|
|
foreach (self::TEMPLATE_PATH as $path) {
|
2020-09-28 01:25:07 +02:00
|
|
|
if (is_dir($path)) {
|
|
|
|
$files = scandir($path);
|
|
|
|
foreach ($files as $k => $file) {
|
|
|
|
if (substr($file, -5) === '.json') {
|
2021-12-01 11:01:31 +01:00
|
|
|
$errorMessage = '';
|
|
|
|
$metaTemplate = $this->decodeTemplateFromDisk($path . $file, $errorMessage);
|
|
|
|
if (!empty($metaTemplate)) {
|
|
|
|
$templates[] = $metaTemplate;
|
|
|
|
} else {
|
|
|
|
$errors[] = $errorMessage;
|
2020-11-20 11:09:24 +01:00
|
|
|
}
|
2020-09-28 01:25:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
return $templates;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function readTemplateFromDisk(string $uuid, &$error=''): ?array
|
|
|
|
{
|
|
|
|
foreach (self::TEMPLATE_PATH as $path) {
|
|
|
|
if (is_dir($path)) {
|
|
|
|
$files = scandir($path);
|
|
|
|
foreach ($files as $k => $file) {
|
|
|
|
if (substr($file, -5) === '.json') {
|
|
|
|
$errorMessage = '';
|
|
|
|
$metaTemplate = $this->decodeTemplateFromDisk($path . $file, $errorMessage);
|
|
|
|
if (!empty($metaTemplate) && $metaTemplate['uuid'] == $uuid) {
|
|
|
|
return $metaTemplate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$error = __('Could not find meta-template with UUID {0}', $uuid);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function decodeTemplateFromDisk(string $filePath, &$errorMessage=''): ?array
|
|
|
|
{
|
|
|
|
if (file_exists($filePath)) {
|
|
|
|
$explodedPath = explode('/', $filePath);
|
|
|
|
$filename = $explodedPath[count($explodedPath)-1];
|
|
|
|
$contents = file_get_contents($filePath);
|
|
|
|
$metaTemplate = json_decode($contents, true);
|
|
|
|
if (empty($metaTemplate)) {
|
|
|
|
$errorMessage = __('Could not load template file `{0}`. Error while decoding the template\'s JSON', $filename);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if (empty($metaTemplate['uuid']) || empty($metaTemplate['version'])) {
|
|
|
|
$errorMessage = __('Could not load template file. Invalid template file. Missing template UUID or version');
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $metaTemplate;
|
|
|
|
}
|
2020-09-28 01:25:07 +02:00
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function getEntitiesWithMetaFieldsToUpdate(int $template_id): array
|
|
|
|
{
|
|
|
|
$metaTemplate = $this->get($template_id);
|
|
|
|
$queryParentEntities = $this->MetaTemplateFields->MetaFields->find();
|
|
|
|
$queryParentEntities
|
|
|
|
->select(['parent_id'])
|
|
|
|
->where([
|
|
|
|
'meta_template_id' => $template_id
|
|
|
|
])
|
|
|
|
->group(['parent_id']);
|
|
|
|
|
|
|
|
$entitiesClassName = Inflector::camelize(Inflector::pluralize($metaTemplate->scope));
|
|
|
|
$entitiesTable = TableRegistry::getTableLocator()->get($entitiesClassName);
|
|
|
|
$entityQuery = $entitiesTable->find()
|
|
|
|
->where(['id IN' => $queryParentEntities])
|
|
|
|
->contain([
|
|
|
|
'MetaFields' => [
|
|
|
|
'conditions' => [
|
|
|
|
'meta_template_id' => $template_id
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
$entities = $entityQuery->all()->toList();
|
|
|
|
return $entities;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getKeyedMetaFields(string $scope, int $entity_id, array $conditions=[])
|
|
|
|
{
|
|
|
|
$query = $this->MetaTemplateFields->MetaFields->find();
|
|
|
|
$query->where(array_merge(
|
|
|
|
$conditions,
|
|
|
|
[
|
|
|
|
'MetaFields.scope' => $scope,
|
|
|
|
'MetaFields.parent_id' => $entity_id
|
|
|
|
]
|
|
|
|
));
|
|
|
|
$metaFields = $query->all();
|
|
|
|
$data = [];
|
|
|
|
foreach ($metaFields as $metaField) {
|
|
|
|
if (empty($data[$metaField->meta_template_id][$metaField->meta_template_field_id])) {
|
|
|
|
$data[$metaField->meta_template_id][$metaField->meta_template_field_id] = [];
|
|
|
|
}
|
|
|
|
$data[$metaField->meta_template_id][$metaField->meta_template_field_id][$metaField->id] = $metaField;
|
|
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function mergeMetaFieldsInMetaTemplate(array $keyedMetaFields, array $metaTemplates)
|
|
|
|
{
|
|
|
|
$merged = [];
|
|
|
|
foreach ($metaTemplates as $metaTemplate) {
|
|
|
|
$metaTemplate['meta_template_fields'] = Hash::combine($metaTemplate['meta_template_fields'], '{n}.id', '{n}');
|
|
|
|
$merged[$metaTemplate->id] = $metaTemplate;
|
|
|
|
if (isset($keyedMetaFields[$metaTemplate->id])) {
|
|
|
|
foreach ($metaTemplate->meta_template_fields as $j => $meta_template_field) {
|
|
|
|
if (isset($keyedMetaFields[$metaTemplate->id][$meta_template_field->id])) {
|
|
|
|
$merged[$metaTemplate->id]->meta_template_fields[$j]['metaFields'] = $keyedMetaFields[$metaTemplate->id][$meta_template_field->id];
|
|
|
|
} else {
|
|
|
|
$merged[$metaTemplate->id]->meta_template_fields[$j]['metaFields'] = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $merged;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function migrateMetaTemplateToNewVersion(\App\Model\Entity\MetaTemplate $oldMetaTemplate, \App\Model\Entity\MetaTemplate $newMetaTemplate, int $entityId)
|
|
|
|
{
|
|
|
|
$entitiesClassName = Inflector::camelize(Inflector::pluralize($oldMetaTemplate->scope));
|
|
|
|
$entitiesTable = TableRegistry::getTableLocator()->get($entitiesClassName);
|
|
|
|
$entity = $entitiesTable->get($entityId, [
|
|
|
|
'contain' => 'MetaFields'
|
|
|
|
]);
|
|
|
|
return $entity;
|
|
|
|
}
|
|
|
|
|
2020-11-20 11:09:24 +01:00
|
|
|
public function getTemplate($id)
|
|
|
|
{
|
|
|
|
$query = $this->find();
|
|
|
|
$query->where(['id' => $id]);
|
|
|
|
$template = $query->first();
|
|
|
|
if (empty($template)) {
|
|
|
|
throw new NotFoundException(__('Invalid template ID specified.'));
|
|
|
|
}
|
|
|
|
return $template;
|
|
|
|
}
|
|
|
|
|
2020-12-10 16:50:46 +01:00
|
|
|
public function getDefaultTemplatePerScope(String $scope = '')
|
|
|
|
{
|
|
|
|
$query = $this->find('list', [
|
|
|
|
'keyField' => 'scope',
|
|
|
|
'valueField' => function ($template) {
|
|
|
|
return $template;
|
|
|
|
}
|
|
|
|
])->where(['is_default' => true]);
|
|
|
|
if (!empty($scope)) {
|
|
|
|
$query->where(['scope' => $scope]);
|
|
|
|
}
|
|
|
|
return $query->all()->toArray();
|
|
|
|
}
|
|
|
|
|
2020-12-10 17:18:17 +01:00
|
|
|
public function removeDefaultFlag(String $scope)
|
|
|
|
{
|
|
|
|
$this->updateAll(
|
|
|
|
['is_default' => false],
|
|
|
|
['scope' => $scope]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
// public function loadAndSaveMetaFile(String $filePath)
|
|
|
|
// {
|
|
|
|
// if (file_exists($filePath)) {
|
|
|
|
// $contents = file_get_contents($filePath);
|
|
|
|
// $metaTemplate = json_decode($contents, true);
|
|
|
|
// if (empty($metaTemplate)) {
|
|
|
|
// return __('Could not load template file. Error while decoding the template\'s JSON');
|
|
|
|
// }
|
|
|
|
// if (empty($metaTemplate['uuid']) || empty($metaTemplate['version'])) {
|
|
|
|
// return __('Could not load template file. Invalid template file. Missing template UUID or version');
|
|
|
|
// }
|
|
|
|
// return $this->saveMetaFile($metaTemplate);
|
|
|
|
// }
|
|
|
|
// return __('Could not load template file. File does not exists');
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public function saveMetaFile(array $newMetaTemplate)
|
|
|
|
// {
|
|
|
|
// $query = $this->find();
|
|
|
|
// $query->contain('MetaTemplateFields')->where(['uuid' => $newMetaTemplate['uuid']]);
|
|
|
|
// $metaTemplate = $query->first();
|
|
|
|
// if (empty($metaTemplate)) {
|
|
|
|
// $metaTemplate = $this->newEntity($newMetaTemplate);
|
|
|
|
// $result = $this->save($metaTemplate);
|
|
|
|
// if (!$result) {
|
|
|
|
// return __('Something went wrong, could not create the template.');
|
|
|
|
// }
|
|
|
|
// } else {
|
|
|
|
// if ($metaTemplate->version >= $newMetaTemplate['version']) {
|
|
|
|
// return __('Could not update the template. Local version is newer.');
|
|
|
|
// }
|
|
|
|
// // Take care of meta template fields
|
|
|
|
// $metaTemplate = $this->patchEntity($metaTemplate, $newMetaTemplate);
|
|
|
|
// $metaTemplate = $this->save($metaTemplate);
|
|
|
|
// if (!$metaTemplate) {
|
|
|
|
// return __('Something went wrong, could not update the template.');
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// if ($result) {
|
|
|
|
// $this->MetaTemplateFields->deleteAll(['meta_template_id' => $template->id]);
|
|
|
|
// foreach ($newMetaTemplate['metaFields'] as $metaField) {
|
|
|
|
// $metaField['meta_template_id'] = $template->id;
|
|
|
|
// $metaField = $this->MetaTemplateFields->newEntity($metaField);
|
|
|
|
// $this->MetaTemplateFields->save($metaField);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
public function saveNewMetaTemplate(array $template, array &$errors=[], &$savedMetaTemplate=null): bool
|
2020-09-28 01:25:07 +02:00
|
|
|
{
|
2021-12-08 11:11:46 +01:00
|
|
|
$template['meta_template_fields'] = $template['metaFields'];
|
|
|
|
unset($template['metaFields']);
|
|
|
|
$metaTemplate = $this->newEntity($template, [
|
|
|
|
'associated' => ['MetaTemplateFields']
|
|
|
|
]);
|
|
|
|
$tmp = $this->save($metaTemplate, [
|
|
|
|
'associated' => ['MetaTemplateFields']
|
|
|
|
]);
|
|
|
|
$error = null;
|
|
|
|
if (empty($tmp)) {
|
|
|
|
$error = new UpdateError();
|
|
|
|
$error->success = false;
|
|
|
|
$error->message = __('Could not save the template.');
|
|
|
|
$error->errors = $metaTemplate->getErrors();
|
|
|
|
$errors[] = $error;
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
$savedMetaTemplate = $tmp;
|
|
|
|
return !is_null($error);
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2020-09-28 01:25:07 +02:00
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function updateMetaTemplate(array $template, array &$errors=[]): bool
|
2021-11-24 09:14:09 +01:00
|
|
|
{
|
2021-12-08 11:11:46 +01:00
|
|
|
$metaTemplate = $this->getMetaTemplateElligibleForUpdate($template);
|
|
|
|
if (is_string($metaTemplate)) {
|
|
|
|
$errors[] = new UpdateError(false, $metaTemplate);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$metaTemplate = $this->patchEntity($metaTemplate, $template, [
|
|
|
|
'associated' => ['MetaTemplateFields']
|
|
|
|
]);
|
|
|
|
$metaTemplate = $this->save($metaTemplate, [
|
|
|
|
'associated' => ['MetaTemplateFields']
|
|
|
|
]);
|
|
|
|
if (!empty($metaTemplate)) {
|
|
|
|
$errors[] = new UpdateError(false, __('Could not save the template.'), $metaTemplate->getErrors());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function updateMetaTemplateWithStrategy(array $template, string $strategy, array $errors=[]): bool
|
|
|
|
{
|
|
|
|
$metaTemplate = $this->getMetaTemplateElligibleForUpdate($template);
|
|
|
|
if (is_string($metaTemplate)) {
|
|
|
|
$errors[] = new UpdateError(false, $metaTemplate);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$success = $this->executeUpdateStrategy($strategy, $template, $metaTemplate);
|
|
|
|
if (is_string($success)) {
|
|
|
|
$errors[] = new UpdateError(false, $success);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMetaTemplateElligibleForUpdate($template)
|
|
|
|
{
|
|
|
|
$query = $this->find()
|
|
|
|
->contain('MetaTemplateFields')->where([
|
|
|
|
'uuid' => $template['uuid']
|
|
|
|
]);
|
2021-11-24 09:14:09 +01:00
|
|
|
$metaTemplate = $query->first();
|
|
|
|
if (empty($metaTemplate)) {
|
2021-12-08 11:11:46 +01:00
|
|
|
return __('Meta-template not found.');
|
|
|
|
}
|
|
|
|
if ($metaTemplate->version >= $template['version']) {
|
|
|
|
return __('Could not update the template. Local version is newer.');
|
|
|
|
}
|
|
|
|
return $metaTemplate;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function executeUpdateStrategy(string $strategy, array $template, \App\Model\Entity\MetaTemplate $metaTemplate)
|
|
|
|
{
|
|
|
|
if ($strategy == 'keep_both') {
|
|
|
|
$result = $this->executeStrategyKeep($template, $metaTemplate);
|
|
|
|
} else if ($strategy == 'delete_all') {
|
|
|
|
$result = $this->executeStrategyDeleteAll($template, $metaTemplate);
|
2021-11-24 09:14:09 +01:00
|
|
|
} else {
|
2021-12-08 11:11:46 +01:00
|
|
|
return __('Invalid strategy {0}', $strategy);
|
|
|
|
}
|
|
|
|
if (is_string($result)) {
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Old template remains untouched
|
|
|
|
// Create new template
|
|
|
|
// Migrate all non-conflicting meta-fields for one entity to the new template
|
|
|
|
// Keep all the conflicting meta-fields for one entity on the old template
|
|
|
|
public function executeStrategyKeep(array $template, \App\Model\Entity\MetaTemplate $metaTemplate)
|
|
|
|
{
|
|
|
|
$savedMetaTemplate = null;
|
|
|
|
$conflicts = $this->checkForMetaTemplateConflicts($metaTemplate, $template);
|
|
|
|
$blockingConflict = Hash::extract($conflicts, '{s}.conflicts');
|
|
|
|
$errors = [];
|
|
|
|
if (empty($blockingConflict)) { // No conflict, everything can be updated without special care
|
|
|
|
$this->updateMetaTemplate($template, $errors);
|
|
|
|
return !empty($errors) ? $errors[0] : true;
|
|
|
|
}
|
|
|
|
$entities = $this->fetchEntitiesWithMetaFieldsForTemplate($metaTemplate);
|
|
|
|
|
|
|
|
$conflictingEntities = [];
|
|
|
|
foreach ($entities as $entity) {
|
|
|
|
$conflicts = $this->checkMetaFieldsValidityUnderTemplate($entity['meta_fields'], $template);
|
|
|
|
if (!empty($conflicts)) {
|
|
|
|
$conflictingEntities[$entity->id] = $entity->id;
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
}
|
|
|
|
if (empty($conflictingEntities)) {
|
|
|
|
$this->updateMetaTemplate($template, $errors);
|
|
|
|
return !empty($errors) ? $errors[0] : true;
|
|
|
|
}
|
|
|
|
$template['is_default'] = $metaTemplate['is_default'];
|
|
|
|
$template['enabled'] = $metaTemplate['enabled'];
|
|
|
|
if ($metaTemplate->is_default) {
|
|
|
|
$metaTemplate->set('is_default', false);
|
|
|
|
$this->save($metaTemplate);
|
|
|
|
}
|
|
|
|
$success = $this->saveNewMetaTemplate($template, $errors, $savedMetaTemplate);
|
|
|
|
if (!empty($savedMetaTemplate)) { // conflicting entities remain untouched
|
|
|
|
$savedMetaTemplateFieldByName = Hash::combine($savedMetaTemplate['meta_template_fields'], '{n}.field', '{n}');
|
|
|
|
foreach ($entities as $entity) {
|
|
|
|
if (empty($conflictingEntities[$entity->id])) {
|
|
|
|
foreach ($entity['meta_fields'] as $metaField) {
|
|
|
|
$savedMetaTemplateField = $savedMetaTemplateFieldByName[$metaField->field];
|
|
|
|
$success = $this->replaceMetaTemplate($metaField, $savedMetaTemplateField);
|
|
|
|
}
|
|
|
|
}
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
} else {
|
|
|
|
return $errors[0]->message;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete conflicting meta-fields
|
|
|
|
// Update template to the new version
|
|
|
|
public function executeStrategyDeleteAll($template, $metaTemplate)
|
|
|
|
{
|
|
|
|
$errors = [];
|
|
|
|
$conflicts = $this->checkForMetaTemplateConflicts($metaTemplate, $template);
|
|
|
|
$blockingConflict = Hash::extract($conflicts, '{s}.conflicts');
|
|
|
|
if (empty($blockingConflict)) { // No conflict, everything can be updated without special care
|
|
|
|
$this->updateMetaTemplate($template, $errors);
|
|
|
|
return !empty($errors) ? $errors[0] : true;
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
$entities = $this->fetchEntitiesWithMetaFieldsForTemplate($metaTemplate);
|
|
|
|
|
|
|
|
foreach ($entities as $entity) {
|
|
|
|
$conflicts = $this->checkMetaFieldsValidityUnderTemplate($entity['meta_fields'], $template);
|
|
|
|
$result = $this->MetaTemplateFields->MetaFields->deleteAll([
|
|
|
|
'id IN' => $conflicts
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
$this->updateMetaTemplate($template, $errors);
|
|
|
|
return !empty($errors) ? $errors[0] : true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function replaceMetaTemplate(\App\Model\Entity\MetaField $metaField, \App\Model\Entity\MetaTemplateField $savedMetaTemplateField)
|
|
|
|
{
|
|
|
|
$metaField->set('meta_template_id', $savedMetaTemplateField->meta_template_id);
|
|
|
|
$metaField->set('meta_template_field_id', $savedMetaTemplateField->id);
|
|
|
|
$metaField = $this->MetaTemplateFields->MetaFields->save($metaField);
|
|
|
|
return !empty($metaField);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function checkMetaFieldsValidityUnderTemplate(array $metaFields, array $template): array
|
|
|
|
{
|
|
|
|
$conflicting = [];
|
|
|
|
$metaTemplateFieldByName = [];
|
|
|
|
foreach ($template['metaFields'] as $metaField) {
|
|
|
|
$metaTemplateFieldByName[$metaField['field']] = $this->MetaTemplateFields->newEntity($metaField);
|
|
|
|
}
|
|
|
|
foreach ($metaFields as $metaField) {
|
|
|
|
$isValid = $this->MetaTemplateFields->MetaFields->isValidMetaFieldForMetaTemplateField(
|
|
|
|
$metaField->value,
|
|
|
|
$metaTemplateFieldByName[$metaField->field]
|
|
|
|
);
|
|
|
|
if ($isValid !== true) {
|
|
|
|
$conflicting[] = $metaField;
|
2020-09-28 01:25:07 +02:00
|
|
|
}
|
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
return $conflicting;
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2020-09-28 01:25:07 +02:00
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function checkMetaFieldsValidityUnderExistingMetaTemplate(array $metaFields, \App\Model\Entity\MetaTemplate $metaTemplate): array
|
2021-11-24 09:14:09 +01:00
|
|
|
{
|
2021-12-08 11:11:46 +01:00
|
|
|
$conflicting = [];
|
|
|
|
$metaTemplateFieldByName = [];
|
|
|
|
foreach ($metaTemplate->meta_template_fields as $metaTemplateField) {
|
|
|
|
$metaTemplateFieldByName[$metaTemplateField->field] = $metaTemplateField;
|
|
|
|
}
|
|
|
|
foreach ($metaFields as $metaField) {
|
|
|
|
if ($metaField->meta_template_id != $metaTemplate->id) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$isValid = $this->MetaTemplateFields->MetaFields->isValidMetaFieldForMetaTemplateField(
|
|
|
|
$metaField->value,
|
|
|
|
$metaTemplateFieldByName[$metaField->field]
|
|
|
|
);
|
|
|
|
if ($isValid !== true) {
|
|
|
|
$conflicting[] = $metaField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $conflicting;
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function fetchEntitiesWithMetaFieldsForTemplate(\App\Model\Entity\MetaTemplate $metaTemplate): array
|
|
|
|
{
|
|
|
|
$entitiesIDWithMetaFields = $this->MetaTemplateFields->MetaFields->find()
|
|
|
|
->select(['parent_id', 'scope'])
|
|
|
|
->where(['MetaFields.meta_template_id' => $metaTemplate->id])
|
|
|
|
->group('parent_id')
|
|
|
|
->all()
|
|
|
|
->toList();
|
|
|
|
$className = Inflector::camelize(Inflector::pluralize($entitiesIDWithMetaFields[0]->scope));
|
|
|
|
|
|
|
|
$table = TableRegistry::getTableLocator()->get($className);
|
|
|
|
$entities = $table->find()
|
|
|
|
->where(['id IN' => Hash::extract($entitiesIDWithMetaFields, '{n}.parent_id')])
|
|
|
|
->contain([
|
|
|
|
'MetaFields' => [
|
|
|
|
'conditions' => [
|
|
|
|
'MetaFields.meta_template_id' => $metaTemplate->id
|
|
|
|
]
|
|
|
|
]
|
|
|
|
])
|
|
|
|
->all()->toList();
|
|
|
|
|
|
|
|
return $entities;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function checkForMetaFieldConflicts(\App\Model\Entity\MetaTemplateField $metaTemplateField, array $templateField): array
|
2021-12-01 11:01:31 +01:00
|
|
|
{
|
|
|
|
$result = [
|
|
|
|
'updateable' => true,
|
|
|
|
'conflicts' => [],
|
2021-12-08 11:11:46 +01:00
|
|
|
'conflictingEntities' => [],
|
2021-12-01 11:01:31 +01:00
|
|
|
];
|
2021-12-08 11:11:46 +01:00
|
|
|
if ($metaTemplateField->multiple && $templateField['multiple'] == false) { // Field is no longer multiple
|
|
|
|
$query = $this->MetaTemplateFields->MetaFields->find();
|
|
|
|
$query
|
|
|
|
->enableHydration(false)
|
|
|
|
->select([
|
|
|
|
'parent_id',
|
|
|
|
'meta_template_field_id',
|
|
|
|
'count' => $query->func()->count('meta_template_field_id'),
|
|
|
|
])
|
|
|
|
->where([
|
|
|
|
'meta_template_field_id' => $metaTemplateField->id,
|
|
|
|
])
|
|
|
|
->group(['parent_id'])
|
|
|
|
->having(['count >' => 1]);
|
|
|
|
$conflictingStatus = $query->all()->toList();
|
|
|
|
if (!empty($conflictingStatus)) {
|
|
|
|
$result['updateable'] = false;
|
|
|
|
$result['conflicts'][] = __('This field is no longer multiple');
|
|
|
|
$result['conflictingEntities'] = Hash::extract($conflictingStatus, '{n}.parent_id');
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
if (!empty($templateField['regex']) && $templateField['regex'] != $metaTemplateField->regex) {
|
|
|
|
$query = $this->MetaTemplateFields->MetaFields->find();
|
|
|
|
$query
|
|
|
|
->enableHydration(false)
|
|
|
|
->select([
|
|
|
|
'parent_id',
|
|
|
|
'scope',
|
|
|
|
'meta_template_field_id',
|
|
|
|
])
|
|
|
|
->where([
|
|
|
|
'meta_template_field_id' => $metaTemplateField->id,
|
|
|
|
]);
|
|
|
|
$entitiesWithMetaField = $query->all()->toList();
|
|
|
|
if (!empty($entitiesWithMetaField)) {
|
|
|
|
$className = Inflector::camelize(Inflector::pluralize($entitiesWithMetaField[0]['scope']));
|
|
|
|
$table = TableRegistry::getTableLocator()->get($className);
|
|
|
|
$entities = $table->find()
|
|
|
|
->where(['id IN' => Hash::extract($entitiesWithMetaField, '{n}.parent_id')])
|
|
|
|
->contain([
|
|
|
|
'MetaFields' => [
|
|
|
|
'conditions' => [
|
|
|
|
'MetaFields.meta_template_field_id' => $metaTemplateField->id
|
|
|
|
]
|
|
|
|
]
|
|
|
|
])
|
|
|
|
->all()->toList();
|
|
|
|
$conflictingEntities = [];
|
|
|
|
foreach ($entities as $entity) {
|
|
|
|
foreach ($entity['meta_fields'] as $metaField) {
|
|
|
|
$isValid = $this->MetaTemplateFields->MetaFields->isValidMetaFieldForMetaTemplateField(
|
|
|
|
$metaField->value,
|
|
|
|
$templateField
|
|
|
|
);
|
|
|
|
if ($isValid !== true) {
|
|
|
|
$conflictingEntities[] = $entity->id;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!empty($conflictingEntities)) {
|
|
|
|
$result['updateable'] = $result['updateable'] && false;
|
|
|
|
$result['conflicts'][] = __('This field is instantiated with values not passing the validation anymore');
|
|
|
|
$result['conflictingEntities'] = $conflictingEntities;
|
|
|
|
}
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function checkForMetaTemplateConflicts(\App\Model\Entity\MetaTemplate $metaTemplate, $template): array
|
2021-12-01 11:01:31 +01:00
|
|
|
{
|
2021-12-08 11:11:46 +01:00
|
|
|
$templateMetaFields = [];
|
|
|
|
if (!is_array($template) && get_class($template) == 'App\Model\Entity\MetaTemplate') {
|
|
|
|
$templateMetaFields = $template->meta_template_fields;
|
|
|
|
} else {
|
|
|
|
$templateMetaFields = $template['metaFields'];
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
$conflicts = [];
|
|
|
|
$existingMetaTemplateFields = Hash::combine($metaTemplate->toArray(), 'meta_template_fields.{n}.field');
|
2021-12-08 11:11:46 +01:00
|
|
|
foreach ($templateMetaFields as $newMetaField) {
|
2021-12-01 11:01:31 +01:00
|
|
|
foreach ($metaTemplate->meta_template_fields as $metaField) {
|
|
|
|
if ($newMetaField['field'] == $metaField->field) {
|
|
|
|
unset($existingMetaTemplateFields[$metaField->field]);
|
2021-12-08 11:11:46 +01:00
|
|
|
$templateConflicts = $this->checkForMetaFieldConflicts($metaField, !is_array($newMetaField) && get_class($newMetaField) == 'App\Model\Entity\MetaTemplateField' ? $newMetaField->toArray() : $newMetaField);
|
|
|
|
$conflicts[$metaField->field] = $templateConflicts;
|
|
|
|
$conflicts[$metaField->field]['existing_meta_template_field'] = $metaField;
|
|
|
|
$conflicts[$metaField->field]['existing_meta_template_field']['conflicts'] = $templateConflicts['conflicts'];
|
2021-12-01 11:01:31 +01:00
|
|
|
}
|
|
|
|
}
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
if (!empty($existingMetaTemplateFields)) {
|
|
|
|
foreach ($existingMetaTemplateFields as $field => $tmp) {
|
|
|
|
$conflicts[$field] = [
|
|
|
|
'updateable' => false,
|
|
|
|
'conflicts' => [__('This field is intended to be removed')],
|
|
|
|
];
|
|
|
|
}
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
return $conflicts;
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:11:46 +01:00
|
|
|
public function checkUpdatesForTemplate($template, $metaTemplate=null): array
|
2021-12-01 11:01:31 +01:00
|
|
|
{
|
|
|
|
$result = [
|
|
|
|
'new' => true,
|
|
|
|
'up-to-date' => false,
|
|
|
|
'updateable' => false,
|
|
|
|
'conflicts' => [],
|
|
|
|
'template' => $template,
|
|
|
|
];
|
2021-12-08 11:11:46 +01:00
|
|
|
if (is_null($metaTemplate)) {
|
|
|
|
$query = $this->find()
|
|
|
|
->contain('MetaTemplateFields')
|
|
|
|
->where([
|
|
|
|
'uuid' => $template['uuid'],
|
|
|
|
])
|
|
|
|
->order(['version' => 'DESC']);
|
|
|
|
$metaTemplate = $query->first();
|
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
if (!empty($metaTemplate)) {
|
|
|
|
$result['existing_template'] = $metaTemplate;
|
|
|
|
$result['current_version'] = $metaTemplate->version;
|
|
|
|
$result['next_version'] = $template['version'];
|
|
|
|
$result['new'] = false;
|
|
|
|
if ($metaTemplate->version >= $template['version']) {
|
|
|
|
$result['up-to-date'] = true;
|
|
|
|
$result['updateable'] = false;
|
|
|
|
$result['conflicts'][] = __('Could not update the template. Local version is equal or newer.');
|
|
|
|
return $result;
|
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
|
2021-12-01 11:01:31 +01:00
|
|
|
$conflicts = $this->checkForMetaTemplateConflicts($metaTemplate, $template);
|
|
|
|
if (!empty($conflicts)) {
|
|
|
|
$result['conflicts'] = $conflicts;
|
|
|
|
} else {
|
|
|
|
$result['updateable'] = true;
|
|
|
|
}
|
2021-11-24 09:14:09 +01:00
|
|
|
}
|
2021-12-01 11:01:31 +01:00
|
|
|
return $result;
|
2020-09-28 01:25:07 +02:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
|
|
|
|
public function checkUpdateForMetaTemplate($template, $metaTemplate): array
|
|
|
|
{
|
|
|
|
$result = $this->checkUpdatesForTemplate($template, $metaTemplate);
|
|
|
|
$result['meta_field_amount'] = $this->MetaTemplateFields->MetaFields->find()->where(['meta_template_id' => $metaTemplate->id])->count();
|
|
|
|
$result['can_be_removed'] = empty($result['meta_field_amount']) && empty($result['to_existing']);
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function massageMetaFieldsBeforeSave($entity, $input, $metaTemplate)
|
|
|
|
{
|
|
|
|
$metaFieldsTable = $this->MetaTemplateFields->MetaFields;
|
|
|
|
$className = Inflector::camelize(Inflector::pluralize($metaTemplate->scope));
|
|
|
|
$entityTable = TableRegistry::getTableLocator()->get($className);
|
|
|
|
$metaFieldsIndex = [];
|
|
|
|
if (!empty($entity->meta_fields)) {
|
|
|
|
foreach ($entity->meta_fields as $i => $metaField) {
|
|
|
|
$metaFieldsIndex[$metaField->id] = $i;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$entity->meta_fields = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
$metaFieldsToDelete = [];
|
|
|
|
foreach ($input['MetaTemplates'] as $template_id => $template) {
|
|
|
|
foreach ($template['meta_template_fields'] as $meta_template_field_id => $meta_template_field) {
|
|
|
|
$rawMetaTemplateField = $metaTemplate->meta_template_fields[$meta_template_field_id];
|
|
|
|
foreach ($meta_template_field['metaFields'] as $meta_field_id => $meta_field) {
|
|
|
|
if ($meta_field_id == 'new') { // create new meta_field
|
|
|
|
$new_meta_fields = $meta_field;
|
|
|
|
foreach ($new_meta_fields as $new_value) {
|
|
|
|
if (!empty($new_value)) {
|
|
|
|
$metaField = $metaFieldsTable->newEmptyEntity();
|
|
|
|
$metaFieldsTable->patchEntity($metaField, [
|
|
|
|
'value' => $new_value,
|
|
|
|
'scope' => $entityTable->getBehavior('MetaFields')->getScope(),
|
|
|
|
'field' => $rawMetaTemplateField->field,
|
|
|
|
'meta_template_id' => $rawMetaTemplateField->meta_template_id,
|
|
|
|
'meta_template_field_id' => $rawMetaTemplateField->id,
|
|
|
|
'parent_id' => $entity->id,
|
|
|
|
'uuid' => Text::uuid(),
|
|
|
|
]);
|
|
|
|
$entity->meta_fields[] = $metaField;
|
|
|
|
$entity->MetaTemplates[$template_id]->meta_template_fields[$meta_template_field_id]->metaFields[] = $metaField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$new_value = $meta_field['value'];
|
|
|
|
if (!empty($new_value)) { // update meta_field and attach validation errors
|
|
|
|
if (!empty($metaFieldsIndex[$meta_field_id])) {
|
|
|
|
$index = $metaFieldsIndex[$meta_field_id];
|
|
|
|
$metaFieldsTable->patchEntity($entity->meta_fields[$index], [
|
|
|
|
'value' => $new_value, 'meta_template_field_id' => $rawMetaTemplateField->id
|
|
|
|
], ['value']);
|
|
|
|
$metaFieldsTable->patchEntity(
|
|
|
|
$entity->MetaTemplates[$template_id]->meta_template_fields[$meta_template_field_id]->metaFields[$meta_field_id],
|
|
|
|
['value' => $new_value, 'meta_template_field_id' => $rawMetaTemplateField->id],
|
|
|
|
['value']
|
|
|
|
);
|
|
|
|
} else { // metafield comes from a second post where the temporary entity has already been created
|
|
|
|
$metaField = $metaFieldsTable->newEmptyEntity();
|
|
|
|
$metaFieldsTable->patchEntity($metaField, [
|
|
|
|
'value' => $new_value,
|
|
|
|
'scope' => $entityTable->getBehavior('MetaFields')->getScope(), // get scope from behavior
|
|
|
|
'field' => $rawMetaTemplateField->field,
|
|
|
|
'meta_template_id' => $rawMetaTemplateField->meta_template_id,
|
|
|
|
'meta_template_field_id' => $rawMetaTemplateField->id,
|
|
|
|
'parent_id' => $entity->id,
|
|
|
|
'uuid' => Text::uuid(),
|
|
|
|
]);
|
|
|
|
$entity->meta_fields[] = $metaField;
|
|
|
|
$entity->MetaTemplates[$template_id]->meta_template_fields[$meta_template_field_id]->metaFields[] = $metaField;
|
|
|
|
}
|
|
|
|
} else { // Metafield value is empty, indicating the field should be removed
|
|
|
|
$index = $metaFieldsIndex[$meta_field_id];
|
|
|
|
$metaFieldsToDelete[] = $entity->meta_fields[$index];
|
|
|
|
unset($entity->meta_fields[$index]);
|
|
|
|
unset($entity->MetaTemplates[$template_id]->meta_template_fields[$meta_template_field_id]->metaFields[$meta_field_id]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$entity->setDirty('meta_fields', true);
|
|
|
|
return ['entity' => $entity, 'metafields_to_delete' => $metaFieldsToDelete];
|
|
|
|
}
|
2020-09-28 01:25:07 +02:00
|
|
|
}
|
2021-12-08 11:11:46 +01:00
|
|
|
|
|
|
|
class UpdateError
|
|
|
|
{
|
|
|
|
public $success;
|
|
|
|
public $message = '';
|
|
|
|
public $errors = [];
|
|
|
|
|
|
|
|
public function __construct($success=false, $message='', $errors=[])
|
|
|
|
{
|
|
|
|
$this->success = $success;
|
|
|
|
$this->message = $message;
|
|
|
|
$this->errors = $errors;
|
|
|
|
}
|
|
|
|
}
|