new: [cerebrate:pull_sg] Pull sharing groups from a cerebrate instance

pull/7731/head
mokaddem 2021-09-06 16:28:23 +02:00
parent 8665076156
commit bcf801e1bd
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
5 changed files with 405 additions and 7 deletions

View File

@ -115,7 +115,7 @@ class CerebratesController extends AppController
$result = $this->Cerebrate->saveRemoteOrgs($result);
$message = __('Added %s new organisations, updated %s existing organisations, %s failures.', $result['add'], $result['edit'], $result['fails']);
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Cerebrates', 'pull_orgs', $cerebrate_id . '/' . $org_id, false, $message);
return $this->RestResponse->saveSuccessResponse('Cerebrates', 'pull_orgs', $cerebrate_id, false, $message);
} else {
$this->Flash->success($message);
$this->redirect($this->referer());
@ -128,10 +128,46 @@ class CerebratesController extends AppController
$this->layout = 'ajax';
$this->render('/genericTemplates/confirm');
}
}
public function pull_sgs($id)
{
$this->set('menuData', ['menuList' => 'sync', 'menuItem' => 'previewCerebrateSgs']);
$cerebrate = $this->Cerebrate->find('first', [
'recursive' => -1,
'conditions' => ['Cerebrate.id' => $id]
]);
if (empty($cerebrate)) {
throw new NotFoundException(__('Invalid Cerebrate instance ID provided.'));
}
if ($this->request->is('post')) {
$result = $this->Cerebrate->queryInstance([
'cerebrate' => $cerebrate,
'path' => '/sharingGroups/index',
'params' => $this->IndexFilter->harvestParameters([
'name',
'uuid',
'quickFilter'
]),
'type' => 'GET'
]);
$result = $this->Cerebrate->saveRemoteSgs($result, $this->Auth->user());
$message = __('Added %s new sharing groups, updated %s existing sharing groups, %s failures.', $result['add'], $result['edit'], $result['fails']);
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Cerebrates', 'pull_sgs', $cerebrate_id, false, $message);
} else {
$this->Flash->success($message);
$this->redirect($this->referer());
}
} else {
$this->set('id', $cerebrate['Cerebrate']['id']);
$this->set('title', __('Sync sharing group information'));
$this->set('question', __('Are you sure you want to download and add / update the remote sharing group from the Cerebrate node?'));
$this->set('actionName', __('Pull all'));
$this->layout = 'ajax';
$this->render('/genericTemplates/confirm');
}
}
public function preview_orgs($id)
@ -186,7 +222,7 @@ class CerebratesController extends AppController
if (is_array($saveResult)) {
return $this->RestResponse->viewData($saveResult, $this->response->type());
} else {
return $this->RestResponse->saveFailResponse('Cerebrates', 'download_org', $cerebrate_id . '/' . $org_id, $aveResult);
return $this->RestResponse->saveFailResponse('Cerebrates', 'download_org', $cerebrate_id . '/' . $org_id, $saveResult);
}
} else {
if (is_array($saveResult)) {
@ -205,4 +241,76 @@ class CerebratesController extends AppController
$this->render('/genericTemplates/confirm');
}
}
public function preview_sharing_groups($id)
{
$this->set('menuData', ['menuList' => 'sync', 'menuItem' => 'previewCerebrateSGs']);
$cerebrate = $this->Cerebrate->find('first', [
'recursive' => -1,
'conditions' => ['Cerebrate.id' => $id]
]);
if (empty($cerebrate)) {
throw new NotFoundException(__('Invalid Cerebrate instance ID provided.'));
}
$result = $this->Cerebrate->queryInstance([
'cerebrate' => $cerebrate,
'path' => '/sharingGroups/index',
'params' => $this->IndexFilter->harvestParameters([
'name',
'uuid',
'quickFilter'
]),
'type' => 'GET'
]);
$result = $this->Cerebrate->checkRemoteSharingGroups($result);
if ($this->_isRest()) {
return $this->RestResponse->viewData($result, $this->response->type());
} else {
App::uses('CustomPaginationTool', 'Tools');
$customPagination = new CustomPaginationTool();
$customPagination->truncateAndPaginate($result, $this->params, false, true);
$this->set('data', $result);
$this->set('cerebrate', $cerebrate);
}
}
public function download_sg($cerebrate_id, $sg_id)
{
if ($this->request->is('post')) {
$cerebrate = $this->Cerebrate->find('first', [
'recursive' => -1,
'conditions' => ['Cerebrate.id' => $cerebrate_id]
]);
if (empty($cerebrate)) {
throw new NotFoundException(__('Invalid Cerebrate instance ID provided.'));
}
$result = $this->Cerebrate->queryInstance([
'cerebrate' => $cerebrate,
'path' => '/sharingGroups/view/' . $sg_id,
'type' => 'GET'
]);
$saveResult = $this->Cerebrate->captureSg($result, $this->Auth->user());
if ($this->_isRest()) {
if (is_array($saveResult)) {
return $this->RestResponse->viewData($saveResult, $this->response->type());
} else {
return $this->RestResponse->saveFailResponse('Cerebrates', 'download_sg', $cerebrate_id . '/' . $sg_id, $saveResult);
}
} else {
if (is_array($saveResult)) {
$this->Flash->success(__('Sharing Group downloaded.'));
} else {
$this->Flash->error($saveResult);
}
$this->redirect($this->referer());
}
} else {
$this->set('id', $cerebrate_id);
$this->set('title', __('Download sharing group information'));
$this->set('question', __('Are you sure you want to download and add / update the remote sharing group?'));
$this->set('actionName', __('Download'));
$this->layout = 'ajax';
$this->render('/genericTemplates/confirm');
}
}
}

View File

@ -109,6 +109,32 @@ class Cerebrate extends AppModel
return $outcome;
}
public function saveRemoteSgs($sgs, $user)
{
$outcome = [
'add' => 0,
'edit' => 0,
'fails' => 0
];
foreach ($sgs as $sg) {
$isEdit = false;
$noChange = false;
$result = $this->captureSg($sg, $user, $isEdit, $noChange);
if (!is_array($result)) {
$outcome['fails'] += 1;
} else {
if ($isEdit) {
if (!$noChange) {
$outcome['edit'] += 1;
}
} else {
$outcome['add'] += 1;
}
}
}
return $outcome;
}
public function captureOrg($org_data, &$edit=false, &$noChange=false) {
$org = $this->convertOrg($org_data);
if ($org) {
@ -226,6 +252,165 @@ class Cerebrate extends AppModel
}
return false;
}
}
?>
private function __compareMembers($existingMembers, $remoteMembers)
{
$memberFound = [];
$memberNotFound = [];
foreach ($remoteMembers as $remoteMember) {
$found = false;
foreach ($existingMembers as $existingMember) {
if ($existingMember['uuid'] == $remoteMember['uuid']) {
$found = true;
$memberFound[] = $remoteMember['uuid'];
break;
}
}
if (!$found) {
$memberNotFound[] = $remoteMember['uuid'];
}
}
return empty($memberNotFound);
}
/*
* Checks remote for the current status of each sharing groups
* Adds the exists_locally field with a boolean status
* If exists_loally is true, adds a list with the differences (keynames)
*/
public function checkRemoteSharingGroups($sgs)
{
$this->SharingGroup = ClassRegistry::init('SharingGroup');
$uuids = Hash::extract($sgs, '{n}.uuid');
$existingSgs = $this->SharingGroup->find('all', [
'recursive' => -1,
'contain' => [
'SharingGroupOrg' => ['Organisation'],
'Organisation',
],
'conditions' => [
'SharingGroup.uuid' => $uuids
],
]);
$rearranged = [];
foreach ($existingSgs as $existingSg) {
$existingSg['SharingGroup']['SharingGroupOrg'] = $existingSg['SharingGroupOrg'];
$existingSg['SharingGroup']['Organisation'] = $existingSg['Organisation'];
$rearranged[$existingSg['SharingGroup']['uuid']] = $existingSg['SharingGroup'];
}
unset($existingSgs);
$fieldsToCheck = ['name', 'releasability', 'description'];
foreach ($sgs as $k => $sg) {
$sgs[$k]['exists_locally'] = false;
if (isset($rearranged[$sg['uuid']])) {
$sgs[$k]['exists_locally'] = true;
$sgs[$k]['differences'] = $this->compareSgs($rearranged[$sg['uuid']], $sgs[$k]);
}
}
return $sgs;
}
private function compareSgs($existingSg, $remoteSg)
{
$differences = [];
$fieldsToCheck = ['name', 'releasability', 'description'];
foreach ($fieldsToCheck as $fieldToCheck) {
if (
!(empty($remoteSg[$fieldToCheck]) && empty($existingSg[$fieldToCheck])) &&
$remoteSg[$fieldToCheck] !== $existingSg[$fieldToCheck]
) {
if ($fieldToCheck === 'name') {
if ($this->__compareNames($existingSg[$fieldToCheck], $remoteSg[$fieldToCheck])) {
continue;
}
}
$differences[] = $fieldToCheck;
}
}
if (!$this->__compareMembers(Hash::extract($existingSg['SharingGroupOrg'], '{n}.Organisation'), $remoteSg['sharing_group_orgs'])) {
$differences[] = 'members';
}
return $differences;
}
private function convertSg($sg_data)
{
$mapping = [
'name' => [
'field' => 'name',
'required' => 1
],
'uuid' => [
'field' => 'uuid',
'required' => 1
],
'releasability' => [
'field' => 'releasability'
],
'description' => [
'field' => 'description'
],
];
$sg = [];
foreach ($mapping as $cerebrate_field => $field_data) {
if (empty($sg_data[$cerebrate_field])) {
if (!empty($field_data['required'])) {
return false;
} else {
continue;
}
}
$sg[$field_data['field']] = $sg_data[$cerebrate_field];
}
$sg['SharingGroupOrg'] = [];
if (!empty($sg_data['sharing_group_orgs'])) {
$sg['SharingGroupOrg'] = $sg_data['sharing_group_orgs'];
foreach ($sg['SharingGroupOrg'] as $k => $org) {
if (isset($org['_joinData'])) {
unset($sg['SharingGroupOrg'][$k]['_joinData']);
}
if (!isset($org['extend'])) {
$sg['SharingGroupOrg'][$k]['extend'] = false;
}
}
}
return $sg;
}
public function captureSg($sg_data, $user, &$edit=false, &$noChange=false) {
$this->SharingGroup = ClassRegistry::init('SharingGroup');
$sg = $this->convertSg($sg_data);
if ($sg) {
$existingSg = $this->SharingGroup->find('first', [
'recursive' => -1,
'contain' => [
'SharingGroupOrg' => ['Organisation'],
'Organisation',
],
'conditions' => [
'SharingGroup.uuid' => $sg_data['uuid']
],
]);
if (!empty($existingSg)) {
$edit = true;
}
$captureResult = $this->SharingGroup->captureSG($sg, $user, false);
if (!empty($captureResult)) {
$savedSg = $this->SharingGroup->find('first', [
'recursive' => -1,
'contain' => [
'SharingGroupOrg' => ['Organisation'],
'Organisation',
],
'conditions' => [
'SharingGroup.id' => $captureResult
],
]);
return $savedSg;
}
return __('The organisation could not be saved.');
}
return __('The retrieved data isn\'t a valid sharing group.');
}
}

View File

@ -92,6 +92,15 @@
'title' => __('Pull all organisations'),
'icon' => 'arrow-circle-down'
],
[
'onclick' => sprintf(
'openGenericModal(\'%s/cerebrates/pull_sgs/[onclick_params_data_path]\');',
$baseurl
),
'onclick_params_data_path' => 'Cerebrate.id',
'title' => __('Pull all sharing groups'),
'icon' => 'arrow-circle-down'
],
[
'url' => $baseurl . '/cerebrates/edit',
'url_params_data_paths' => ['Cerebrate.id'],

View File

@ -0,0 +1,90 @@
<?php
$fields = [
[
'name' => __('Id'),
'sort' => 'id',
'data_path' => 'id'
],
[
'name' => __('Status'),
'sort' => 'exists_locally',
'element' => 'remote_status',
'data_path' => ''
],
[
'name' => __('UUID'),
'sort' => 'uuid',
'data_path' => 'uuid'
],
[
'name' => __('Name'),
'sort' => 'name',
'data_path' => 'name'
],
[
'name' => __('Releasability'),
'sort' => 'releasability',
'data_path' => 'releasability'
],
[
'name' => __('Description'),
'sort' => 'description',
'data_path' => 'description'
],
[
'name' => __('# Member'),
'element' => 'custom',
'function' => function($row) {
return count($row['sharing_group_orgs']);
}
],
];
echo $this->element('genericElements/IndexTable/scaffold', [
'scaffold_data' => [
'data' => [
'data' => $data,
'top_bar' => [
'pull' => 'right',
'children' => [
[
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
'preserve_url_params' => [$cerebrate['Cerebrate']['id']],
'searchKey' => 'quickFilter'
]
]
],
'fields' => $fields,
'title' => empty($ajax) ? __(
'Sharing group list via Cerebrate %s (%s)',
h($cerebrate['Cerebrate']['id']),
h($cerebrate['Cerebrate']['name'])
) : false,
'description' => empty($ajax) ? __('Preview of the sharing group known to the remote Cerebrate instance.') : false,
'actions' => [
[
'onclick' => sprintf(
'openGenericModal(\'%s/cerebrates/download_sg/%s/[onclick_params_data_path]\');',
$baseurl,
h($cerebrate['Cerebrate']['id'])
),
'onclick_params_data_path' => 'id',
'icon' => 'download',
'title' => __('Fetch sharing group object')
]
],
'paginatorOptions' => [
'url' => [$cerebrate['Cerebrate']['id']]
],
'persistUrlParams' => [0, 'quickFilter']
],
'containerId' => 'preview_sgs_container'
]
]);
?>
<script type="text/javascript">
var passedArgsArray = <?= json_encode([h($cerebrate['Cerebrate']['id'])]) ?>;
</script>

View File

@ -56,7 +56,13 @@ echo $this->element(
'url_params' => ['Cerebrate.id'],
'title' => __('Organisations'),
'elementId' => 'preview_orgs_container'
]
],
[
'url' => '/cerebrates/preview_sharing_groups/{{0}}/',
'url_params' => ['Cerebrate.id'],
'title' => __('Sharing Groups'),
'elementId' => 'preview_sgs_container'
],
]
]
);