2020-09-28 01:25:07 +02:00
< ? php
namespace App\Controller ;
use App\Controller\AppController ;
use Cake\Utility\Hash ;
use Cake\Utility\Text ;
2021-12-08 11:11:46 +01:00
use Cake\Utility\Inflector ;
use Cake\ORM\TableRegistry ;
2020-09-28 01:25:07 +02:00
use \Cake\Database\Expression\QueryExpression ;
2021-12-08 11:11:46 +01:00
use Cake\Http\Exception\NotFoundException ;
use Cake\Http\Exception\MethodNotAllowedException ;
2020-09-28 01:25:07 +02:00
class MetaTemplatesController extends AppController
{
2021-11-09 09:11:35 +01:00
public $quickFilterFields = [[ 'name' => true ], 'uuid' , [ 'scope' => true ]];
2021-09-10 11:55:54 +02:00
public $filterFields = [ 'name' , 'uuid' , 'scope' , 'namespace' ];
public $containFields = [ 'MetaTemplateFields' ];
2020-12-08 15:08:12 +01:00
2021-12-14 15:09:40 +01:00
// public function update($template_uuid=null)
// {
// $metaTemplate = false;
// if (!is_null($template_uuid)) {
// $metaTemplate = $this->MetaTemplates->find()->where([
// 'uuid' => $template_uuid
// ])->first();
// if (empty($metaTemplate)) {
// throw new NotFoundException(__('Invalid {0}.', $this->MetaTemplates->getAlias()));
// }
// }
// if ($this->request->is('post')) {
// $updateStrategy = $this->request->getData('update_strategy', null);
// $result = $this->MetaTemplates->update($template_uuid, $updateStrategy);
// if ($this->ParamHandler->isRest()) {
// return $this->RestResponse->viewData($result, 'json');
// } else {
// if ($result['success']) {
// $message = __n('{0} templates updated.', 'The template has been updated.', empty($template_uuid), $result['files_processed']);
// } else {
// $message = __n('{0} templates could not be updated.', 'The template could not be updated.', empty($template_uuid), $result['files_processed']);
// }
// $this->CRUD->setResponseForController('update', $result['success'], $message, $result['files_processed'], $result['update_errors'], ['redirect' => $this->referer()]);
// $responsePayload = $this->CRUD->getResponsePayload();
// if (!empty($responsePayload)) {
// return $responsePayload;
// }
// }
// } else {
// if (!$this->ParamHandler->isRest()) {
// if (!is_null($template_uuid)) {
// $this->set('metaTemplate', $metaTemplate);
// $this->setUpdateStatus($metaTemplate->id);
// } else {
// $this->set('title', __('Update Meta Templates'));
// $this->set('question', __('Are you sure you wish to update the Meta Template definitions'));
// $templatesUpdateStatus = $this->MetaTemplates->getUpdateStatusForTemplates();
// $this->set('templatesUpdateStatus', $templatesUpdateStatus);
// $this->render('updateAll');
// }
// }
// }
// }
2021-12-15 15:33:58 +01:00
public function updateAllTemplates ()
{
if ( $this -> request -> is ( 'post' )) {
$result = $this -> MetaTemplates -> updateAllTemplates ();
if ( $this -> ParamHandler -> isRest ()) {
return $this -> RestResponse -> viewData ( $result , 'json' );
} else {
if ( $result [ 'success' ]) {
$message = __n ( '{0} templates updated.' , 'The template has been updated.' , empty ( $template_id ), $result [ 'files_processed' ]);
} else {
$message = __n ( '{0} templates could not be updated.' , 'The template could not be updated.' , empty ( $template_id ), $result [ 'files_processed' ]);
}
$this -> CRUD -> setResponseForController ( 'updateAllTemplate' , $result [ 'success' ], $message , $result [ 'files_processed' ], $result [ 'update_errors' ], [ 'redirect' => $this -> referer ()]);
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
}
}
} else {
if ( ! $this -> ParamHandler -> isRest ()) {
$this -> set ( 'title' , __ ( 'Update All Meta Templates' ));
$this -> set ( 'question' , __ ( 'Are you sure you wish to update all the Meta Template definitions' ));
$templatesUpdateStatus = $this -> MetaTemplates -> getUpdateStatusForTemplates ();
$this -> set ( 'templatesUpdateStatus' , $templatesUpdateStatus );
$this -> render ( 'updateAll' );
}
}
}
2021-12-14 15:09:40 +01:00
/**
* Update the provided template or all templates
*
* @ param int | null $template_id
*/
public function update ( $template_id = null )
2020-09-28 01:25:07 +02:00
{
2021-12-08 11:11:46 +01:00
$metaTemplate = false ;
2021-12-14 15:09:40 +01:00
if ( ! is_null ( $template_id )) {
if ( ! is_numeric ( $template_id )) {
throw new NotFoundException ( __ ( 'Invalid {0} for provided ID.' , $this -> MetaTemplates -> getAlias (), $template_id ));
}
$metaTemplate = $this -> MetaTemplates -> get ( $template_id );
2021-12-08 11:11:46 +01:00
if ( empty ( $metaTemplate )) {
2021-12-14 15:09:40 +01:00
throw new NotFoundException ( __ ( 'Invalid {0} {1}.' , $this -> MetaTemplates -> getAlias (), $template_id ));
2021-12-08 11:11:46 +01:00
}
2021-11-24 09:14:09 +01:00
}
2020-11-20 11:09:24 +01:00
if ( $this -> request -> is ( 'post' )) {
2021-12-14 15:09:40 +01:00
$params = $this -> ParamHandler -> harvestParams ([ 'update_strategy' ]);
$updateStrategy = $params [ 'update_strategy' ] ? ? null ;
$result = $this -> MetaTemplates -> update ( $metaTemplate , $updateStrategy );
2020-11-20 11:09:24 +01:00
if ( $this -> ParamHandler -> isRest ()) {
return $this -> RestResponse -> viewData ( $result , 'json' );
} else {
2021-11-24 09:14:09 +01:00
if ( $result [ 'success' ]) {
2021-12-14 15:09:40 +01:00
$message = __n ( '{0} templates updated.' , 'The template has been updated.' , empty ( $template_id ), $result [ 'files_processed' ]);
2021-11-24 09:14:09 +01:00
} else {
2021-12-14 15:09:40 +01:00
$message = __n ( '{0} templates could not be updated.' , 'The template could not be updated.' , empty ( $template_id ), $result [ 'files_processed' ]);
2021-11-24 09:14:09 +01:00
}
2021-12-08 11:11:46 +01:00
$this -> CRUD -> setResponseForController ( 'update' , $result [ 'success' ], $message , $result [ 'files_processed' ], $result [ 'update_errors' ], [ 'redirect' => $this -> referer ()]);
2021-11-24 09:14:09 +01:00
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
}
2020-11-20 11:09:24 +01:00
}
} else {
if ( ! $this -> ParamHandler -> isRest ()) {
2021-12-14 15:09:40 +01:00
if ( ! empty ( $metaTemplate )) {
2021-12-01 11:01:31 +01:00
$this -> set ( 'metaTemplate' , $metaTemplate );
2021-12-14 15:09:40 +01:00
$statuses = $this -> setUpdateStatus ( $metaTemplate -> id );
$this -> set ( 'updateStatus' , $this -> MetaTemplates -> computeFullUpdateStatusForMetaTemplate ( $statuses [ 'templateStatus' ], $metaTemplate ));
2021-11-24 09:14:09 +01:00
} else {
2021-12-14 15:09:40 +01:00
$this -> set ( 'title' , __ ( 'Update All Meta Templates' ));
$this -> set ( 'question' , __ ( 'Are you sure you wish to update all the Meta Template definitions' ));
$templatesUpdateStatus = $this -> MetaTemplates -> getUpdateStatusForTemplates ();
$this -> set ( 'templatesUpdateStatus' , $templatesUpdateStatus );
2021-12-01 11:01:31 +01:00
$this -> render ( 'updateAll' );
2021-11-24 09:14:09 +01:00
}
2020-11-20 11:09:24 +01:00
}
}
2020-09-28 01:25:07 +02:00
}
2021-12-08 11:11:46 +01:00
public function getMetaFieldsToUpdate ( $template_id )
{
$metaTemplate = $this -> MetaTemplates -> get ( $template_id );
$newestMetaTemplate = $this -> MetaTemplates -> getNewestVersion ( $metaTemplate );
2021-12-14 15:09:40 +01:00
$entities = $this -> MetaTemplates -> getEntitiesHavingMetaFieldsFromTemplate ( $template_id );
2021-12-08 11:11:46 +01:00
$this -> set ( 'metaTemplate' , $metaTemplate );
$this -> set ( 'newestMetaTemplate' , $newestMetaTemplate );
$this -> set ( 'entities' , $entities );
}
public function migrateOldMetaTemplateToNewestVersionForEntity ( $template_id , $entity_id )
{
$metaTemplate = $this -> MetaTemplates -> get ( $template_id , [
'contain' => [ 'MetaTemplateFields' ]
]);
$newestMetaTemplate = $this -> MetaTemplates -> getNewestVersion ( $metaTemplate , true );
2021-12-14 15:09:40 +01:00
$entity = $this -> MetaTemplates -> getEntity ( $metaTemplate , $entity_id );
2021-12-08 11:11:46 +01:00
$conditions = [
2021-12-14 15:09:40 +01:00
'MetaFields.meta_template_id IN' => [ $metaTemplate -> id , $newestMetaTemplate -> id ],
'MetaFields.scope' => $metaTemplate -> scope ,
2021-12-08 11:11:46 +01:00
];
2021-12-14 15:09:40 +01:00
$keyedMetaFields = $this -> MetaTemplates -> getKeyedMetaFieldsForEntity ( $entity_id , $conditions );
2021-12-08 11:11:46 +01:00
if ( empty ( $keyedMetaFields [ $metaTemplate -> id ])) {
throw new NotFoundException ( __ ( 'Invalid {0}. This entities does not have meta-fields to be moved to a newer template.' , $this -> MetaTemplates -> getAlias ()));
}
2021-12-14 15:09:40 +01:00
$mergedMetaFields = $this -> MetaTemplates -> insertMetaFieldsInMetaTemplates ( $keyedMetaFields , [ $metaTemplate , $newestMetaTemplate ]);
2021-12-08 11:11:46 +01:00
$entity [ 'MetaTemplates' ] = $mergedMetaFields ;
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
$className = Inflector :: camelize ( Inflector :: pluralize ( $newestMetaTemplate -> scope ));
$entityTable = TableRegistry :: getTableLocator () -> get ( $className );
$inputData = $this -> request -> getData ();
$massagedData = $this -> MetaTemplates -> massageMetaFieldsBeforeSave ( $entity , $inputData , $newestMetaTemplate );
unset ( $inputData [ 'MetaTemplates' ]); // Avoid MetaTemplates to be overriden when patching entity
$data = $massagedData [ 'entity' ];
$metaFieldsToDelete = $massagedData [ 'metafields_to_delete' ];
foreach ( $entity -> meta_fields as $i => $metaField ) {
if ( $metaField -> meta_template_id == $template_id ) {
$metaFieldsToDelete [] = $entity -> meta_fields [ $i ];
}
}
$data = $entityTable -> patchEntity ( $data , $inputData );
$savedData = $entityTable -> save ( $data );
if ( $savedData !== false ) {
if ( ! empty ( $metaFieldsToDelete )) {
$entityTable -> MetaFields -> unlink ( $savedData , $metaFieldsToDelete );
}
$message = __ ( 'Data on old meta-template has been migrated to newest meta-template' );
} else {
$message = __ ( 'Could not migrate data to newest meta-template' );
}
$this -> CRUD -> setResponseForController (
'migrateOldMetaTemplateToNewestVersionForEntity' ,
$savedData !== false ,
$message ,
$savedData ,
[],
[ 'redirect' => [
'controller' => $className ,
'action' => 'view' , $entity_id ]
]
);
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
}
}
2021-12-14 15:09:40 +01:00
$conflicts = $this -> MetaTemplates -> getMetaTemplateConflictsForMetaTemplate ( $metaTemplate , $newestMetaTemplate );
2021-12-08 11:11:46 +01:00
foreach ( $conflicts as $conflict ) {
2021-12-14 15:09:40 +01:00
if ( ! empty ( $conflict [ 'existing_meta_template_field' ])) {
$existingMetaTemplateField = $conflict [ 'existing_meta_template_field' ];
foreach ( $existingMetaTemplateField -> metaFields as $metaField ) {
$metaField -> setError ( 'value' , implode ( ', ' , $existingMetaTemplateField -> conflicts ));
}
2021-12-08 11:11:46 +01:00
}
}
// automatically convert non-conflicting fields to new meta-template
$movedMetaTemplateFields = [];
foreach ( $metaTemplate -> meta_template_fields as $metaTemplateField ) {
if ( ! empty ( $conflicts [ $metaTemplateField -> field ][ 'conflicts' ])) {
continue ;
}
foreach ( $newestMetaTemplate -> meta_template_fields as $newMetaTemplateField ) {
if ( $metaTemplateField -> field == $newMetaTemplateField -> field && empty ( $newMetaTemplateField -> metaFields )) {
$movedMetaTemplateFields [] = $metaTemplateField -> id ;
$copiedMetaFields = array_map ( function ( $e ) use ( $newMetaTemplateField ) {
$e = $e -> toArray ();
$e [ 'meta_template_id' ] = $newMetaTemplateField -> meta_template_id ;
$e [ 'meta_template_field_id' ] = $newMetaTemplateField -> id ;
unset ( $e [ 'id' ]);
return $e ;
}, $metaTemplateField -> metaFields );
$newMetaTemplateField -> metaFields = $this -> MetaTemplates -> MetaTemplateFields -> MetaFields -> newEntities ( $copiedMetaFields );
}
}
}
$this -> set ( 'oldMetaTemplate' , $metaTemplate );
$this -> set ( 'newMetaTemplate' , $newestMetaTemplate );
$this -> set ( 'entity' , $entity );
$this -> set ( 'conflicts' , $conflicts );
$this -> set ( 'movedMetaTemplateFields' , $movedMetaTemplateFields );
}
2020-09-28 01:25:07 +02:00
public function index ()
{
2021-12-14 15:09:40 +01:00
$templatesUpdateStatus = $this -> MetaTemplates -> getUpdateStatusForTemplates ();
2020-09-28 01:25:07 +02:00
$this -> CRUD -> index ([
2021-09-10 11:55:54 +02:00
'filters' => $this -> filterFields ,
'quickFilters' => $this -> quickFilterFields ,
2020-12-08 15:08:12 +01:00
'contextFilters' => [
'custom' => [
[
2021-12-14 15:09:40 +01:00
'default' => true ,
'label' => __ ( 'Newest Templates' ),
'filterConditionFunction' => function ( $query ) {
return $query -> where ([
'id IN' => $this -> MetaTemplates -> genQueryForAllNewestVersionIDs ()
]);
}
2020-12-08 15:08:12 +01:00
],
]
],
2021-12-01 11:01:31 +01:00
'contain' => $this -> containFields ,
2021-12-14 15:09:40 +01:00
'afterFind' => function ( $data ) use ( $templatesUpdateStatus ) {
2021-12-01 11:01:31 +01:00
foreach ( $data as $i => $metaTemplate ) {
2021-12-14 15:09:40 +01:00
if ( ! empty ( $templatesUpdateStatus [ $metaTemplate -> uuid ])) {
$templateStatus = $this -> MetaTemplates -> getStatusForMetaTemplate ( $templatesUpdateStatus [ $metaTemplate -> uuid ][ 'template' ], $metaTemplate );
$metaTemplate -> set ( 'updateStatus' , $this -> MetaTemplates -> computeFullUpdateStatusForMetaTemplate ( $templateStatus , $metaTemplate ));
2021-12-01 11:01:31 +01:00
}
}
return $data ;
}
2020-09-28 01:25:07 +02:00
]);
2021-06-29 16:15:05 +02:00
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
2020-09-28 01:25:07 +02:00
}
2021-12-14 15:09:40 +01:00
$updateableTemplates = [
'not-up-to-date' => $this -> MetaTemplates -> getNotUpToDateTemplates (),
'can-be-removed' => $this -> MetaTemplates -> getCanBeRemovedTemplates (),
2021-12-01 11:01:31 +01:00
'new' => $this -> MetaTemplates -> getNewTemplates (),
];
2020-12-10 16:50:46 +01:00
$this -> set ( 'defaultTemplatePerScope' , $this -> MetaTemplates -> getDefaultTemplatePerScope ());
2020-09-28 01:25:07 +02:00
$this -> set ( 'alignmentScope' , 'individuals' );
2021-12-14 15:09:40 +01:00
$this -> set ( 'updateableTemplates' , $updateableTemplates );
2020-09-28 01:25:07 +02:00
}
public function view ( $id )
{
$this -> CRUD -> view ( $id , [
'contain' => [ 'MetaTemplateFields' ]
]);
2021-06-29 16:15:05 +02:00
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
2020-09-28 01:25:07 +02:00
}
2021-12-01 11:01:31 +01:00
$this -> setUpdateStatus ( $id );
2020-09-28 01:25:07 +02:00
}
2020-11-20 11:09:24 +01:00
2021-12-08 11:11:46 +01:00
public function delete ( $id )
{
$updateableTemplate = $this -> getUpdateStatus ( $id );
2021-12-14 15:09:40 +01:00
if ( empty ( $updateableTemplate [ 'can-be-removed' ])) {
2021-12-08 11:11:46 +01:00
throw MethodNotAllowedException ( __ ( 'This meta-template cannot be removed' ));
}
$this -> set ( 'deletionText' , __ ( 'The meta-template "{0}" has no meta-field and can be safely removed.' , h ( $updateableTemplate [ 'existing_template' ] -> name )));
$this -> CRUD -> delete ( $id );
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
}
}
2020-12-10 15:18:02 +01:00
public function toggle ( $id , $fieldName = 'enabled' )
2020-11-20 11:09:24 +01:00
{
2020-12-10 17:18:17 +01:00
if ( $this -> request -> is ( 'POST' ) && $fieldName == 'is_default' ) {
$template = $this -> MetaTemplates -> get ( $id );
$this -> MetaTemplates -> removeDefaultFlag ( $template -> scope );
$this -> CRUD -> toggle ( $id , $fieldName , [ 'force_state' => ! $template -> is_default ]);
} else {
$this -> CRUD -> toggle ( $id , $fieldName );
}
2021-06-29 16:15:05 +02:00
$responsePayload = $this -> CRUD -> getResponsePayload ();
if ( ! empty ( $responsePayload )) {
return $responsePayload ;
2020-11-20 11:09:24 +01:00
}
}
2021-12-01 11:01:31 +01:00
2021-12-08 11:11:46 +01:00
private function getUpdateStatus ( $id ) : array
{
$metaTemplate = $this -> MetaTemplates -> get ( $id , [
'contain' => [ 'MetaTemplateFields' ]
]);
$templateOnDisk = $this -> MetaTemplates -> readTemplateFromDisk ( $metaTemplate -> uuid );
2021-12-14 15:09:40 +01:00
$templateStatus = $this -> MetaTemplates -> getStatusForMetaTemplate ( $templateOnDisk , $metaTemplate );
return $templateStatus ;
2021-12-08 11:11:46 +01:00
}
2021-12-14 15:09:40 +01:00
/**
* Retreive the template stored on disk and compute the status for the provided template id .
*
* @ param [ type ] $id
* @ return array
*/
private function setUpdateStatus ( $template_id ) : array
2021-12-01 11:01:31 +01:00
{
2021-12-14 15:09:40 +01:00
$metaTemplate = $this -> MetaTemplates -> get ( $template_id , [
2021-12-08 11:11:46 +01:00
'contain' => [ 'MetaTemplateFields' ]
]);
2021-12-01 11:01:31 +01:00
$templateOnDisk = $this -> MetaTemplates -> readTemplateFromDisk ( $metaTemplate -> uuid );
2021-12-14 15:09:40 +01:00
$templateStatus = $this -> MetaTemplates -> getStatusForMetaTemplate ( $templateOnDisk , $metaTemplate );
2021-12-01 11:01:31 +01:00
$this -> set ( 'templateOnDisk' , $templateOnDisk );
2021-12-14 15:09:40 +01:00
$this -> set ( 'templateStatus' , $templateStatus );
return [
'templateOnDisk' => $templateOnDisk ,
'templateStatus' => $templateStatus ,
];
2021-12-01 11:01:31 +01:00
}
2020-09-28 01:25:07 +02:00
}