new: [collections] feature added. Still missing sync integration - WiP

notes
iglocska 2024-01-28 18:05:29 +01:00
parent 553e328f1d
commit 846c130fa3
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
14 changed files with 1116 additions and 3 deletions

View File

@ -0,0 +1,143 @@
<?php
use PHPUnit\Framework\MockObject\InvalidMethodNameException;
App::uses('AppController', 'Controller');
class CollectionElementsController extends AppController
{
public $components = ['Session', 'RequestHandler'];
public $paginate = [
'limit' => 60,
'order' => []
];
public $uses = [
];
public function add($collection_id)
{
$this->CollectionElement->Collection->current_user = $this->Auth->user();
if (!$this->CollectionElement->Collection->mayModify($this->Auth->user('id'), intval($collection_id))) {
throw new MethodNotAllowedException(__('Invalid Collection or insuficient privileges'));
}
$this->CRUD->add([
'beforeSave' => function (array $collectionElement) use ($collection_id) {
$collectionElement['CollectionElement']['collection_id'] = intval($collection_id);
return $collectionElement;
}
]);
if ($this->restResponsePayload) {
return $this->restResponsePayload;
}
$dropdownData = [
'types' => array_combine($this->CollectionElement->valid_types, $this->CollectionElement->valid_types)
];
$this->set(compact('dropdownData'));
$this->set('menuData', array('menuList' => 'collections', 'menuItem' => 'add_element'));
}
public function delete($element_id)
{
$collectionElement = $this->CollectionElement->find('first', [
'recursive' => -1,
'conditions' => [
'CollectionElement.id' => $element_id
]
]);
$collection_id = $collectionElement['CollectionElement']['collection_id'];
if (!$this->CollectionElement->Collection->mayModify($this->Auth->user('id'), $collection_id)) {
throw new MethodNotAllowedException(__('Invalid Collection or insuficient privileges'));
}
$this->CRUD->delete($element_id);
if ($this->restResponsePayload) {
return $this->restResponsePayload;
}
}
public function index($collection_id)
{
$this->set('menuData', array('menuList' => 'collections', 'menuItem' => 'index'));
if (!$this->CollectionElement->Collection->mayView($this->Auth->user('id'), intval($collection_id))) {
throw new NotFoundException(__('Invalid collection or no access.'));
}
$params = [
'filters' => ['uuid', 'type', 'name'],
'quickFilters' => ['name'],
'conditions' => ['collection_id' => $collection_id]
];
$this->loadModel('Event');
$this->set('distributionLevels', $this->Event->distributionLevels);
$this->CRUD->index($params);
if ($this->IndexFilter->isRest()) {
return $this->restResponsePayload;
}
}
public function addElementToCollection($element_type, $element_uuid)
{
if ($this->request->is('get')) {
$validCollections = $this->CollectionElement->Collection->find('list', [
'recursive' => -1,
'fields' => ['Collection.id', 'Collection.name'],
'conditions' => ['Collection.orgc_id' => $this->Auth->user('org_id')]
]);
if (empty($validCollections)) {
throw new NotFoundException(__('You don\'t have any collections yet. Make sure you create one first before you can start adding elements.'));
}
$dropdownData = [
'collections' => $validCollections
];
$this->set(compact('dropdownData'));
} else if ($this->request->is('post')) {
if (!isset($this->request->data['CollectionElement'])) {
$this->request->data = ['CollectionElement' => $this->request->data];
}
if (!isset($this->request->data['CollectionElement']['collection_id'])) {
throw new NotFoundException(__('No collection_id specified.'));
}
$collection_id = intval($this->request->data['CollectionElement']['collection_id']);
if (!$this->CollectionElement->Collection->mayModify($this->Auth->user('id'), $collection_id)) {
throw new NotFoundException(__('Invalid collection or not authorized.'));
}
$description = empty($this->request->data['CollectionElement']['description']) ? '' : $this->request->data['CollectionElement']['description'];
$dataToSave = [
'CollectionElement' => [
'element_uuid' => $element_uuid,
'element_type' => $element_type,
'description' => $description,
'collection_id' => $collection_id
]
];
$this->CollectionElement->create();
$error = '';
try {
$result = $this->CollectionElement->save($dataToSave);
} catch (PDOException $e) {
if ($e->errorInfo[0] == 23000) {
$error = __(' Element already in Collection.');
}
}
if ($result) {
$message = __('Element added to the Collection.');
if ($this->IndexFilter->isRest()) {
return $this->RestResponse->saveSuccessResponse('CollectionElements', 'addElementToCollection', false, $this->response->type(), $message);
} else {
$this->Flash->success($message);
$this->redirect(Router::url($this->referer(), true));
}
} else {
$message = __('Element could not be added to the Collection.%s', $error);
if ($this->IndexFilter->isRest()) {
return $this->RestResponse->saveFailResponse('CollectionElements', 'addElementToCollection', false, $message, $this->response->type());
} else {
$this->Flash->error($message);
$this->redirect(Router::url($this->referer(), true));
}
}
}
}
}

View File

@ -0,0 +1,171 @@
<?php
App::uses('AppController', 'Controller');
class CollectionsController extends AppController
{
public $components = ['Session', 'RequestHandler'];
public $paginate = [
'limit' => 60,
'order' => []
];
public $uses = [
];
private $valid_types = [
'campaign',
'intrusion_set',
'named_threat',
'other',
'research'
];
public function add()
{
$this->Collection->current_user = $this->Auth->user();
$params = [];
if ($this->request->is('post')) {
$data = $this->request->data;
$params = [
'afterSave' => function (array $collection) use ($data) {
$this->Collection->CollectionElement->captureElements($collection);
return $collection;
}
];
}
$this->CRUD->add($params);
if ($this->restResponsePayload) {
return $this->restResponsePayload;
}
$this->set('menuData', array('menuList' => 'collections', 'menuItem' => 'add'));
$this->loadModel('Event');
$dropdownData = [
'types' => array_combine($this->valid_types, $this->valid_types),
'distributionLevels' => $this->Event->distributionLevels,
'sgs' => $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1)
];
$this->set('initialDistribution', Configure::read('MISP.default_event_distribution'));
$this->set(compact('dropdownData'));
$this->render('add');
}
public function edit($id)
{
$this->Collection->current_user = $this->Auth->user();
if (!$this->Collection->mayModify($this->Auth->user('id'), $id)) {
throw new MethodNotAllowedException(__('Invalid Collection or insuficient privileges'));
}
$params = [];
if ($this->request->is('post') || $this->request->is('put')) {
$oldCollection = $this->Collection->find('first', [
'recursive' => -1,
'conditions' => ['Collection.id' => intval($id)]
]);
if (empty($oldCollection)) {
throw new NotFoundException(__('Invalid collection.'));
}
if (empty($this->request->data['Collection'])) {
$this->request->data = ['Collection' => $this->request->data];
}
$data = $this->request->data;
if (
isset($data['Collection']['modified']) &&
$data['Collection']['modified'] <= $oldCollection['Collection']['modified']
) {
throw new ForbiddenException(__('Collection received older or same as local version.'));
}
$params = [
'afterSave' => function (array &$collection) use ($data) {
$collection = $this->Collection->CollectionElement->captureElements($collection);
return $collection;
}
];
}
$this->set('id', $id);
$this->CRUD->edit($id, $params);
if ($this->IndexFilter->isRest()) {
return $this->restResponsePayload;
}
$this->set('menuData', array('menuList' => 'collections', 'menuItem' => 'edit'));
$this->loadModel('Event');
$dropdownData = [
'types' => $this->valid_types,
'distributionLevels' => $this->Event->distributionLevels,
'sgs' => $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1)
];
$this->set(compact('dropdownData'));
$this->render('add');
}
public function delete($id)
{
if (!$this->Collection->mayModify($this->Auth->user('id'), $id)) {
throw new MethodNotAllowedException(__('Invalid Collection or insuficient privileges'));
}
$this->CRUD->delete($id);
if ($this->IndexFilter->isRest()) {
return $this->restResponsePayload;
}
}
public function view($id)
{
$this->set('mayModify', $this->Collection->mayModify($this->Auth->user('id'), $id));
if (!$this->Collection->mayView($this->Auth->user('id'), $id)) {
throw new MethodNotAllowedException(__('Invalid Collection or insuficient privileges'));
}
$this->set('menuData', array('menuList' => 'collections', 'menuItem' => 'view'));
$params = [
'contain' => [
'Orgc',
'Org',
'User',
'CollectionElement'
],
'afterFind' => function (array $collection){
return $this->Collection->rearrangeCollection($collection);
}
];
$this->CRUD->view($id, $params);
if ($this->IndexFilter->isRest()) {
return $this->restResponsePayload;
}
$this->set('id', $id);
$this->loadModel('Event');
$this->set('distributionLevels', $this->Event->distributionLevels);
$this->render('view');
}
public function index($filter = null)
{
$this->set('menuData', array('menuList' => 'collections', 'menuItem' => 'index'));
$params = [
'filters' => ['Collection.uuid', 'Collection.type', 'Collection.name'],
'quickFilters' => ['Collection.name'],
'contain' => ['Orgc'],
'afterFind' => function($collections) {
foreach ($collections as $k => $collection) {
$collections[$k]['Collection']['element_count'] = $this->Collection->CollectionElement->find('count', [
'recursive' => -1,
'conditions' => ['CollectionElement.collection_id' => $collection['Collection']['id']]
]);
}
return $collections;
}
];
if ($filter === 'my_collections') {
$params['conditions']['Collection.user_id'] = $this->Auth->user('id');
}
if ($filter === 'org_collections') {
$params['conditions']['Collection.orgc_id'] = $this->Auth->user('org_id');
}
$this->loadModel('Event');
$this->set('distributionLevels', $this->Event->distributionLevels);
$this->CRUD->index($params);
if ($this->IndexFilter->isRest()) {
return $this->restResponsePayload;
}
}
}

View File

@ -89,6 +89,19 @@ class ACLComponent extends Component
'pull_sgs' => [],
'view' => []
],
'collections' => [
'add' => ['perm_modify'],
'delete' => ['perm_modify'],
'edit' => ['perm_modify'],
'index' => ['*'],
'view' => ['*']
],
'collectionElements' => [
'add' => ['perm_modify'],
'addElementToCollection' => ['perm_modify'],
'delete' => ['perm_modify'],
'index' => ['*']
],
'correlationExclusions' => [
'add' => [],
'edit' => [],

143
app/Model/Collection.php Normal file
View File

@ -0,0 +1,143 @@
<?php
App::uses('AppModel', 'Model');
class Collection extends AppModel
{
public $recursive = -1;
public $actsAs = array(
'Containable'
);
public $belongsTo = [
'Orgc' => array(
'className' => 'Organisation',
'foreignKey' => 'orgc_id',
'fields' => [
'Orgc.id',
'Orgc.uuid',
'Orgc.name'
]
),
'Org' => array(
'className' => 'Organisation',
'foreignKey' => 'org_id',
'fields' => [
'Org.id',
'Org.uuid',
'Org.name'
]
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'fields' => [
'User.id',
'User.email'
]
)
];
public $hasMany = [
'CollectionElement'
];
public $valid_targets = [
'Attribute',
'Event',
'GalaxyCluster',
'Galaxy',
'Object',
'Note',
'Opinion',
'Relationship',
'Organisation',
'SharingGroup'
];
public $current_user = null;
public function beforeValidate($options = array())
{
if (empty($this->data['Collection'])) {
$this->data = ['Collection' => $this->data];
}
if (empty($this->id) && empty($this->data['Collection']['uuid'])) {
$this->data['Collection']['uuid'] = CakeText::uuid();
}
if (empty($this->id)) {
$this->data['Collection']['user_id'] = $this->current_user['id'];
if (empty($this->data['Collection']['orgc_id']) || empty($this->current_user['Role']['perm_sync'])) {
$this->data['Collection']['orgc_id'] = $this->current_user['Organisation']['id'];
}
$this->data['Collection']['org_id'] = $this->current_user['Organisation']['id'];
$this->data['Collection']['user_id'] = $this->current_user['id'];
}
return true;
}
public function mayModify($user_id, $collection_id)
{
$user = $this->User->getAuthUser($user_id);
$collection = $this->find('first', [
'recursive' => -1,
'conditions' => ['Collection.id' => $collection_id]
]);
if ($user['Role']['perm_site_admin']) {
return true;
}
if (empty($user['Role']['perm_modify'])) {
return false;
}
if (!empty($user['Role']['perm_modify_org'])) {
if ($user['org_id'] == $collection['Collection']['Orgc_id']) {
return true;
}
if ($user['Role']['perm_sync'] && $user['org_id'] == $collection['Collection']['Org_id']) {
return true;
}
}
if (!empty($user['Role']['perm_modify']) && $user['id'] === $collection['Collection']['user_id']) {
}
}
public function mayView($user_id, $collection_id)
{
$user = $this->User->getAuthUser($user_id);
$collection = $this->find('first', [
'recursive' => -1,
'conditions' => ['Collection.id' => $collection_id]
]);
if ($user['Role']['perm_site_admin']) {
return true;
}
if ($collection['Collection']['org_id'] == $user('org_id')) {
return true;
}
if (in_array($collection['Collection']['distribution'], [1,2,3])) {
return true;
}
if ($collection['Collection']['distribution'] === 4) {
$SharingGroup = ClassRegistry::init('SharingGroup');
$sgs = $this->SharingGroup->fetchAllAuthorised($user, 'uuid');
if (isset($sgs[$collection['Collection']['sharing_group_id']])) {
return true;
} else {
return false;
}
}
return false;
}
public function rearrangeCollection(array $collection) {
foreach ($collection as $key => $elements) {
if ($key !== 'Collection') {
$collection['Collection'][$key] = $elements;
unset($collection[$key]);
}
}
return $collection;
}
}

View File

@ -0,0 +1,205 @@
<?php
App::uses('AppModel', 'Model');
class CollectionElement extends AppModel
{
public $recursive = -1;
public $actsAs = array(
'Containable'
);
public $belongsTo = array(
'Collection' => array(
'className' => 'Collection',
'foreignKey' => 'collection_id'
)
);
// Make sure you also update the validation for element_type to include anything you add here.
public $valid_types = [
'Event',
'GalaxyCluster'
];
public $validate = [
'collection_id' => [
'numeric' => [
'rule' => ['numeric']
]
],
'uuid' => [
'uuid' => [
'rule' => 'uuid',
'message' => 'Please provide a valid RFC 4122 UUID'
]
],
'element_uuid' => [
'element_uuid' => [
'rule' => 'uuid',
'message' => 'Please provide a valid RFC 4122 UUID'
]
],
'element_type' => [
'element_type' => [
'rule' => ['inList', ['Event', 'GalaxyCluster']],
'message' => 'Invalid object type.'
]
]
];
public function beforeValidate($options = array())
{
// Massage to a common format
if (empty($this->data['CollectionElement'])) {
$this->data = ['CollectionElement' => $this->data];
}
// if we're creating a new element, assign a uuid (unless provided)
if (empty($this->id) && empty($this->data['CollectionElement']['uuid'])) {
$this->data['CollectionElement']['uuid'] = CakeText::uuid();
}
if (
empty($this->id) &&
empty($this->data['CollectionElement']['element_type']) &&
!empty($this->data['CollectionElement']['element_uuid'])
) {
$this->data['CollectionElement']['element_type'] = $this->deduceType($this->data['CollectionElement']['element_uuid']);
}
return true;
}
public function mayModify(int $user_id, int $collection_id)
{
$user = $this->User->getAuthUser($user_id);
$collection = $this->find('first', [
'recursive' => -1,
'conditions' => ['Collection.id' => $collection_id]
]);
if ($user['Role']['perm_site_admin']) {
return true;
}
if (empty($user['Role']['perm_modify'])) {
return false;
}
if (!empty($user['Role']['perm_modify_org'])) {
if ($user['org_id'] == $collection['Collection']['Orgc_id']) {
return true;
}
if ($user['Role']['perm_sync'] && $user['org_id'] == $collection['Collection']['Org_id']) {
return true;
}
}
if (!empty($user['Role']['perm_modify']) && $user['id'] === $collection['Collection']['user_id']) {
}
}
public function mayView(int $user_id, int $collection_id)
{
$user = $this->User->getAuthUser($user_id);
$collection = $this->find('first', [
'recursive' => -1,
'conditions' => ['Collection.id' => $collection_id]
]);
if ($user['Role']['perm_site_admin']) {
return true;
}
if ($collection['Collection']['org_id'] == $user('org_id')) {
return true;
}
if (in_array($collection['Collection']['distribution'], [1,2,3])) {
return true;
}
if ($collection['Collection']['distribution'] === 4) {
$SharingGroup = ClassRegistry::init('SharingGroup');
$sgs = $this->SharingGroup->fetchAllAuthorised($user, 'uuid');
if (isset($sgs[$collection['Collection']['sharing_group_id']])) {
return true;
} else {
return false;
}
}
return false;
}
public function deduceType(string $uuid)
{
foreach ($this->valid_types as $valid_type) {
$this->{$valid_type} = ClassRegistry::init($valid_type);
$result = $this->$valid_type->find('first', [
'conditions' => [$valid_type.'.uuid' => $uuid],
'recursive' => -1
]);
if (!empty($result)) {
return $valid_type;
}
}
throw new NotFoundException(__('Invalid UUID'));
}
/*
* Pass a Collection as received from another instance to this function to capture the elements
* The received object is authoritative, so all elements that no longer exist in the upstream will be culled.
*/
public function captureElements($data) {
$temp = $this->find('all', [
'recursive' => -1,
'conditions' => ['CollectionElement.collection_id' => $data['Collection']['id']]
]);
$oldElements = [];
foreach ($temp as $oldElement) {
$oldElements[$oldElement['CollectionElement']['uuid']] = $oldElement['CollectionElement'];
}
if (isset($data['Collection']['CollectionElement'])) {
$elementsToSave = [];
foreach ($data['Collection']['CollectionElement'] as $k => $element) {
if (empty($element['uuid'])) {
$element['uuid'] = CakeText::uuid();
}
if (isset($oldElements[$element['uuid']])) {
if (isset($element['description'])) {
$oldElements[$element['uuid']]['description'] = $element['description'];
}
$elementsToSave[$k] = $oldElements[$element['uuid']];
unset($oldElements[$element['uuid']]);
} else {
$elementsToSave[$k] = [
'CollectionElement' => [
'uuid' => $element['uuid'],
'element_uuid' => $element['element_uuid'],
'element_type' => $element['element_type'],
'description' => $element['description'],
'collection_id' => $data['Collection']['id']
]
];
}
}
foreach ($elementsToSave as $k => $element) {
if (empty($element['CollectionElement']['id'])) {
$this->create();
}
try{
$this->save($element);
} catch (PDOException $e) {
// duplicate value?
}
}
foreach ($oldElements as $toDelete) {
$this->delete($toDelete['id']);
}
$temp = $this->find('all', [
'conditions' => ['CollectionElement.collection_id' => $data['Collection']['id']],
'recursive' => -1
]);
$data['Collection']['CollectionElement'] = [];
foreach ($temp as $element) {
$data['Collection']['CollectionElement'][] = $element['CollectionElement'];
}
}
return $data;
}
}

View File

@ -0,0 +1,37 @@
<?php
$edit = $this->request->params['action'] === 'edit' ? true : false;
$fields = [
[
'field' => 'element_uuid',
'class' => 'input span6',
'onChange' => 'alert(1);'
],
[
'field' => 'element_type',
'class' => 'input span6',
'options' => $dropdownData['types'],
'type' => 'dropdown'
],
[
'field' => 'description',
'class' => 'span6',
'type' => 'textarea'
]
];
echo $this->element('genericElements/Form/genericForm', [
'data' => [
'description' => null,
'model' => 'CollectionElement',
'title' => __('Add element to Collection'),
'fields' => $fields,
'submit' => [
'action' => $this->request->params['action'],
'ajaxSubmit' => 'submitGenericFormInPlace();'
]
]
]);
if (!$ajax) {
echo $this->element('/genericElements/SideMenu/side_menu', $menuData);
}

View File

@ -0,0 +1,28 @@
<?php
$fields = [
[
'field' => 'collection_id',
'class' => 'input span6',
'options' => $dropdownData['collections'],
'type' => 'dropdown'
],
[
'field' => 'description',
'class' => 'span6',
'type' => 'textarea'
]
];
echo $this->element('genericElements/Form/genericForm', [
'data' => [
'description' => null,
'model' => 'CollectionElement',
'title' => __('Add element to Collection'),
'fields' => $fields,
'submit' => [
'action' => $this->request->params['action'],
//'ajaxSubmit' => 'submitGenericFormInPlace();'
]
]
]);

View File

@ -0,0 +1,61 @@
<?php
$fields = [
[
'name' => __('Id'),
'sort' => 'CollectionElement.id',
'data_path' => 'CollectionElement.id'
],
[
'name' => __('UUID'),
'data_path' => 'CollectionElement.uuid'
],
[
'name' => __('Element'),
'sort' => 'CollectionElement.element_type',
'element' => 'model',
'model_name' => 'CollectionElement.element_type',
'model_id' => 'CollectionElement.element_uuid'
],
[
'name' => __('Element type'),
'data_path' => 'CollectionElement.element_type'
],
[
'name' => __('Description'),
'data_path' => 'CollectionElement.description'
]
];
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' => '',
'searchKey' => 'quickFilter'
]
]
],
'fields' => $fields,
'title' => empty($ajax) ? __('Collection element index') : false,
'actions' => [
[
'onclick' => sprintf(
'openGenericModal(\'%s/collectionElements/delete/[onclick_params_data_path]\');',
$baseurl
),
'onclick_params_data_path' => 'CollectionElement.id',
'icon' => 'trash'
]
]
]
]
]);
?>

View File

@ -0,0 +1,51 @@
<?php
$edit = $this->request->params['action'] === 'edit' ? true : false;
$fields = [
[
'field' => 'name',
'class' => 'span6'
],
[
'field' => 'type',
'class' => 'input span6',
'options' => $dropdownData['types'],
'type' => 'dropdown'
],
[
'field' => 'description',
'class' => 'span6',
'type' => 'textarea'
],
[
'field' => 'distribution',
'class' => 'input',
'options' => $dropdownData['distributionLevels'],
'default' => isset($data['Collection']['distribution']) ? $data['Collection']['distribution'] : $initialDistribution,
'stayInLine' => 1,
'type' => 'dropdown'
],
[
'field' => 'sharing_group_id',
'class' => 'input',
'options' => $dropdownData['sgs'],
'label' => __("Sharing Group"),
'type' => 'dropdown'
]
];
echo $this->element('genericElements/Form/genericForm', [
'data' => [
'description' => __('Create collections to organise data shared by the community into buckets based on commonalities or as part of your research process. Collections are first class citizens and adhere to the same sharing rules as for example events do.'),
'model' => 'Collection',
'title' => $edit ? __('Edit collection') : __('Add new collection'),
'fields' => $fields,
'submit' => [
'action' => $this->request->params['action'],
'ajaxSubmit' => 'submitGenericFormInPlace();'
]
]
]);
if (!$ajax) {
echo $this->element('/genericElements/SideMenu/side_menu', $menuData);
}

View File

@ -0,0 +1,96 @@
<?php
$fields = [
[
'name' => __('Id'),
'sort' => 'Collection.id',
'data_path' => 'Collection.id'
],
[
'name' => __('Name'),
'sort' => 'Collection.name',
'data_path' => 'Collection.name'
],
[
'name' => __('Organisation'),
'sort' => 'Orgc.name',
'data_path' => 'Orgc',
'element' => 'org'
],
[
'name' => __('Elements'),
'sort' => 'Collection.element_count',
'data_path' => 'Collection.element_count'
],
[
'name' => __('UUID'),
'data_path' => 'Collection.uuid'
],
[
'name' => __('Type'),
'data_path' => 'Collection.type'
],
[
'name' => __('Created'),
'sort' => 'Collection.created',
'data_path' => 'Collection.created'
],
[
'name' => __('Modified'),
'sort' => 'Collection.modified',
'data_path' => 'Collection.modified'
],
[
'name' => __('Distribution'),
'sort' => 'distribution',
'data_path' => 'Collection.distribution',
'element' => 'distribution_levels'
],
];
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' => '',
'searchKey' => 'quickFilter'
]
]
],
'fields' => $fields,
'title' => empty($ajax) ? __('Collections index') : false,
'actions' => [
[
'url' => $baseurl . '/collections/view',
'url_params_data_paths' => ['Collection.id'],
'icon' => 'eye'
],
[
'onclick' => sprintf(
'openGenericModal(\'%s/collections/edit/[onclick_params_data_path]\');',
$baseurl
),
'onclick_params_data_path' => 'Collection.id',
'title' => __('Edit Collection'),
'icon' => 'edit'
],
[
'onclick' => sprintf(
'openGenericModal(\'%s/collections/delete/[onclick_params_data_path]\');',
$baseurl
),
'onclick_params_data_path' => 'Collection.id',
'icon' => 'trash'
]
]
]
]
]);
?>

View File

@ -0,0 +1,64 @@
<?php
echo $this->element(
'genericElements/SingleViews/single_view',
[
'title' => __('Collection view'),
'data' => $data,
'fields' => [
[
'key' => __('ID'),
'path' => 'Collection.id'
],
[
'key' => __('UUID'),
'path' => 'Collection.uuid'
],
[
'key' => __('Creator org'),
'path' => 'Collection.orgc_id',
'pathName' => 'Collection.Orgc.name',
'type' => 'model',
'model' => 'organisations'
],
[
'key' => __('Owner org'),
'path' => 'Collection.org_id',
'pathName' => 'Collection.Org.name',
'type' => 'model',
'model' => 'organisations'
],
[
'key' => __('Created'),
'path' => 'Collection.created'
],
[
'key' => __('Modified'),
'path' => 'Collection.modified'
],
[
'key' => __('Name'),
'path' => 'Collection.name'
],
[
'key' => __('Description'),
'path' => 'Collection.description'
],
[
'key' => __('Distribution'),
'path' => 'Collection.distribution',
'event_id_path' => 'Collection.id',
'disable_distribution_graph' => true,
'sg_path' => 'Collection.sharing_group_id',
'type' => 'distribution'
]
],
'children' => [
[
'url' => '/collectionElements/index/{{0}}/',
'url_params' => ['Collection.id'],
'title' => __('Collection elements'),
'elementId' => 'preview_elements_container'
]
]
]
);

View File

@ -1,3 +1,22 @@
<?php
$data = Hash::extract($row, $field['data_path']);
echo h($data['model']) . ' #' . intval($data['model_id']);
if (!empty($field['data_path'])) {
$data = Hash::extract($row, $field['data_path']);
if (isset($data['model_id'])) {
echo h($data['model']) . ' #' . intval($data['model_id']);
}
} else {
$model_name = Hash::extract($row, $field['model_name'])[0];
$model_path = Inflector::Pluralize($model_name);
$model_id = Hash::extract($row, $field['model_id'])[0];
echo sprintf(
'<a href="%s/%s/view/%s">%s (%s)</a>',
$baseurl,
h($model_path),
h($model_id),
h($model_name),
h($model_id)
);
}

View File

@ -265,6 +265,22 @@ $divider = '<li class="divider"></li>';
'text' => __('Download as…')
));
echo $divider;
if ($me['Role']['perm_modify']) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'onClick' => array(
'function' => 'openGenericModal',
'params' => [
sprintf(
'%s/collectionElements/addElementToCollection/Event/%s',
$baseurl,
h($event['Event']['uuid'])
)
]
),
'text' => __('Add Event to Collection')
));
echo $divider;
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/events/index',
'text' => __('List Events')
@ -314,7 +330,50 @@ $divider = '<li class="divider"></li>';
);
}
break;
case 'collections':
if ($menuItem === 'edit' || $menuItem === 'view') {
if ($this->Acl->canAccess('collections', 'add') && $mayModify) {
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'element_id' => 'edit',
'url' => $baseurl . '/collections/edit/' . h($id),
'text' => __('Edit Collection')
]);
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'element_id' => 'delete',
'onClick' => [
'function' => 'openGenericModal',
'params' => array($baseurl . '/Collections/delete/' . h($id))
],
'text' => __('Delete Collection')
]);
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'text' => __('Add Element to Collection'),
'onClick' => [
'function' => 'openGenericModal',
'params' => array($baseurl . '/CollectionElements/add/' . h($id))
],
]);
echo $divider;
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'view',
'url' => $baseurl . '/collections/view/' . h($id),
'text' => __('View Collection')
));
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'index',
'url' => $baseurl . '/collections/index',
'text' => __('List Collections')
));
if ($this->Acl->canAccess('collection', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'add',
'url' => $baseurl . '/collections/add',
'text' => __('Add Collection')
));
}
break;
case 'event-collection':
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'index',
@ -1493,6 +1552,22 @@ $divider = '<li class="divider"></li>';
'text' => __('View Correlation Graph')
));
}
if ($me['Role']['perm_modify']) {
echo $divider;
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'onClick' => array(
'function' => 'openGenericModal',
'params' => [
sprintf(
'%s/collectionElements/addElementToCollection/GalaxyCluster/%s',
$baseurl,
h($cluster['GalaxyCluster']['uuid'])
)
]
),
'text' => __('Add Cluster to Collection')
));
}
}
if ($menuItem === 'view' || $menuItem === 'export') {
echo $divider;

View File

@ -31,6 +31,13 @@
array(
'type' => 'separator'
),
array(
'text' => __('List Collections'),
'url' => $baseurl . '/collections/index'
),
[
'type' => 'separator'
],
array(
'text' => __('View Proposals'),
'url' => $baseurl . '/shadow_attributes/index/all:0'