mirror of https://github.com/MISP/MISP
new: Added first iteration of object references and other changes
- various fixes - rework of the pagination librarypull/2489/head
parent
94fbfed48f
commit
0e7dd2eddc
|
@ -459,6 +459,7 @@ CREATE TABLE IF NOT EXISTS object_references (
|
|||
`uuid` varchar(40) COLLATE utf8_bin DEFAULT NULL,
|
||||
`timestamp` int(11) NOT NULL DEFAULT 0,
|
||||
`object_id` int(11) NOT NULL,
|
||||
`event_id` int(11) NOT NULL,
|
||||
`referenced_id` int(11) NOT NULL,
|
||||
`referenced_type` int(11) NOT NULL DEFAULT 0,
|
||||
`relationship_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
|
||||
|
|
|
@ -716,6 +716,9 @@ class EventsController extends AppController {
|
|||
}
|
||||
|
||||
public function viewEventAttributes($id, $all = false) {
|
||||
if (isset($this->params['named']['focus'])) {
|
||||
$this->set('focus', $this->params['named']['focus']);
|
||||
}
|
||||
$conditions = array('eventid' => $id);
|
||||
if (isset($this->params['named']['deleted']) && $this->params['named']['deleted']) {
|
||||
$conditions['deleted'] = 1;
|
||||
|
@ -774,6 +777,16 @@ class EventsController extends AppController {
|
|||
$this->disableCache();
|
||||
$this->layout = 'ajax';
|
||||
$this->loadModel('Sighting');
|
||||
$uriArray = explode('/', $this->params->here);
|
||||
foreach ($uriArray as $k => $v) {
|
||||
if (strpos($v, ':')) {
|
||||
$temp = explode(':', $v);
|
||||
if ($temp[0] == 'focus') {
|
||||
unset($uriArray[$k]);
|
||||
}
|
||||
}
|
||||
$this->params->here = implode('/', $uriArray);
|
||||
}
|
||||
$this->set('sightingTypes', $this->Sighting->type);
|
||||
$this->set('currentUri', $this->params->here);
|
||||
$this->render('/Elements/eventattribute');
|
||||
|
@ -894,6 +907,7 @@ class EventsController extends AppController {
|
|||
$this->set('typeGroups', array_keys($this->Event->Attribute->typeGroupings));
|
||||
$this->loadModel('Sighting');
|
||||
$this->set('sightingTypes', $this->Sighting->type);
|
||||
$this->set('currentUri', '/events/viewEventAttributes/' . $event['Event']['id']);
|
||||
}
|
||||
|
||||
public function view($id = null, $continue=false, $fromEvent=null) {
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
class ObjectReferencesController extends AppController {
|
||||
|
||||
public $components = array('Security' ,'RequestHandler', 'Session');
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 20,
|
||||
'order' => array(
|
||||
'ObjectReference.id' => 'desc'
|
||||
),
|
||||
);
|
||||
|
||||
public function add($objectId, $targetId = false, $targetType = false) {
|
||||
if (Validation::uuid($objectId)) {
|
||||
$temp = $this->ObjectReference->MispObject->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('Object.id'),
|
||||
'conditions' => array('Object.uuid' => $id)
|
||||
));
|
||||
if (empty($temp)) throw new NotFoundException('Invalid Object');
|
||||
$objectId = $temp['Object']['id'];
|
||||
} else if (!is_numeric($objectId)) {
|
||||
throw new NotFoundException(__('Invalid object'));
|
||||
}
|
||||
$object = $this->ObjectReference->MispObject->find('first', array(
|
||||
'conditions' => array('Object.id' => $objectId),
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'Event' => array(
|
||||
'fields' => array('Event.id', 'Event.orgc_id')
|
||||
)
|
||||
)
|
||||
));
|
||||
if (!$this->userRole['perm_add']) {
|
||||
throw new MethodNotAllowedException('You don\'t have the required permissions to add object reference.');
|
||||
}
|
||||
if (empty($object) || (!$this->_isSiteAdmin() && $object['Event']['orgc_id'] != $this->Auth->user('orgc_id'))) {
|
||||
throw new MethodNotAllowedException('Invalid object.');
|
||||
}
|
||||
$this->set('objectId', $objectId);
|
||||
if ($this->request->is('post')) {
|
||||
$data = array();
|
||||
if (!isset($this->request->data['ObjectReference'])) {
|
||||
$this->request->data['ObjectReference'] = $this->request->data;
|
||||
}
|
||||
$referenced_type = 1;
|
||||
$target_object = $this->ObjectReference->MispObject->find('first', array(
|
||||
'conditions' => array('Object.uuid' => $this->request->data['ObjectReference']['uuid']),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Object.id', 'Object.uuid', 'Object.event_id')
|
||||
));
|
||||
if (!empty($target_object)) {
|
||||
$referenced_id = $target_object['Object']['id'];
|
||||
if ($target_object['Object']['event_id'] != $object['Event']['id']) {
|
||||
throw new NotFoundException('Invalid target. Target has to be within the same event.');
|
||||
}
|
||||
} else {
|
||||
$target_attribute = $this->ObjectReference->MispObject->Attribute->find('first', array(
|
||||
'conditions' => array('Attribute.uuid' => $this->request->data['ObjectReference']['uuid']),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Attribute.id', 'Attribute.uuid', 'Attribute.event_id')
|
||||
));
|
||||
if (empty($target_attribute)) {
|
||||
throw new NotFoundException('Invalid target.');
|
||||
}
|
||||
if ($target_attribute['Attribute']['event_id'] != $object['Event']['id']) {
|
||||
throw new NotFoundException('Invalid target. Target has to be within the same event.');
|
||||
}
|
||||
$referenced_id = $target_attribute['Attribute']['id'];
|
||||
$referenced_type = 0;
|
||||
}
|
||||
$data = array(
|
||||
'referenced_type' => $referenced_type,
|
||||
'referenced_id' => $referenced_id,
|
||||
'uuid' => $this->request->data['ObjectReference']['uuid'],
|
||||
'relationship_type' => !empty($this->request->data['ObjectReference']['relationship_type']) ? $this->request->data['ObjectReference']['relationship_type'] : '',
|
||||
'comment' => !empty($this->request->data['ObjectReference']['comment']) ? $this->request->data['ObjectReference']['comment'] : '',
|
||||
'event_id' => $object['Event']['id'],
|
||||
'object_id' => $objectId
|
||||
);
|
||||
$data['referenced_type'] = $referenced_type;
|
||||
$data['relationship_type'] = $this->request->data['ObjectReference']['relationship_type'];
|
||||
$data['uuid'] = $this->request->data['ObjectReference']['uuid'];
|
||||
$this->ObjectReference->create();
|
||||
$result = $this->ObjectReference->save(array('ObjectReference' => $data));
|
||||
if ($result) {
|
||||
if ($this->_isRest()) {
|
||||
$object = $this->ObjectReference->find("first", array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('ObjectReference' => $this->ObjectReference->id)
|
||||
));
|
||||
return $this->RestResponse->viewData($object, $this->response->type());
|
||||
} else {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Object reference added.')),'status'=>200));
|
||||
}
|
||||
} else {
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('ObjectReferences', 'add', false, $this->ObjectReference->validationErrors, $this->response->type());
|
||||
} else if ($this->request->is('ajax')) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Object reference could not be added.')),'status'=>200));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->describe('ObjectReferences', 'add', false, $this->response->type());
|
||||
} else {
|
||||
$event = $this->ObjectReference->MispObject->Event->find('first', array(
|
||||
'conditions' => array('Event.id' => $object['Event']['id']),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Event.id'),
|
||||
'contain' => array(
|
||||
'Attribute' => array(
|
||||
'conditions' => array('Attribute.deleted' => 0, 'Attribute.object_id' => 0),
|
||||
'fields' => array('Attribute.id', 'Attribute.uuid', 'Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.to_ids')
|
||||
),
|
||||
'Object' => array(
|
||||
'conditions' => array('Object.deleted' => 0),
|
||||
'conditions' => array('NOT' => array('Object.id' => $objectId)),
|
||||
'fields' => array('Object.id', 'Object.uuid', 'Object.name', 'Object.meta-category'),
|
||||
'Attribute' => array(
|
||||
'conditions' => array('Attribute.deleted' => 0),
|
||||
'fields' => array('Attribute.id', 'Attribute.uuid', 'Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.to_ids')
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
$toRearrange = array('Attribute', 'Object');
|
||||
foreach ($toRearrange as $d) {
|
||||
if (!empty($event[$d])) {
|
||||
$temp = array();
|
||||
foreach ($event[$d] as $data) {
|
||||
$temp[$data['uuid']] = $data;
|
||||
}
|
||||
$event[$d] = $temp;
|
||||
}
|
||||
}
|
||||
$this->set('event', $event);
|
||||
$this->set('objectId', $objectId);
|
||||
$this->layout = 'ajax';
|
||||
$this->render('ajax/add');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function delete($id, $hard = false) {
|
||||
|
||||
}
|
||||
|
||||
public function view($id) {
|
||||
|
||||
}
|
||||
}
|
|
@ -165,6 +165,7 @@ class ObjectsController extends AppController {
|
|||
}
|
||||
$objectToSave = $this->MispObject->attributeCleanup($this->request->data);
|
||||
$objectToSave = $this->MispObject->deltaMerge($object, $objectToSave);
|
||||
|
||||
// we pre-validate the attributes before we create an object at this point
|
||||
// This allows us to stop the process and return an error (API) or return
|
||||
// to the add form
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
class CustomPaginationTool {
|
||||
|
||||
function createPaginationRules($items, $options, $model, $sort = 'id') {
|
||||
function createPaginationRules($items, $options, $model, $sort = 'id', $focusKey = 'uuid') {
|
||||
$params = array(
|
||||
'model' => $model,
|
||||
'current' => 1,
|
||||
|
@ -16,7 +16,7 @@ class CustomPaginationTool {
|
|||
'options' => array(
|
||||
),
|
||||
);
|
||||
$validOptions = array('sort', 'direction', 'page');
|
||||
$validOptions = array('sort', 'direction', 'page', 'focus');
|
||||
if ($model == 'events') $validOptions[] = 'attributeFilter';
|
||||
foreach ($validOptions as $v) {
|
||||
if (isset($options[$v])) {
|
||||
|
@ -40,23 +40,38 @@ class CustomPaginationTool {
|
|||
|
||||
function truncateByPagination(&$items, $params) {
|
||||
if (empty($items)) return;
|
||||
$items = array_slice($items, $params['current'] - 1, $params['current'] + $params['limit']);
|
||||
$items = array_slice($items, $params['current'] - 1, $params['limit']);
|
||||
}
|
||||
|
||||
function applyRulesOnArray(&$items, $options, $model, $sort = 'id') {
|
||||
$params = $this->createPaginationRules($items, $options, $model, $sort);
|
||||
function applyRulesOnArray(&$items, $options, $model, $sort = 'id', $focusKey = 'uuid') {
|
||||
$params = $this->createPaginationRules($items, $options, $model, $sort, $focusKey);
|
||||
if (isset($params['sort'])) {
|
||||
$sortArray = array();
|
||||
foreach ($items as $k => $item) {
|
||||
$sortArray[$k] = $item[$params['sort']];
|
||||
$sortArray[$k] = empty($item[$params['sort']]) ? '' : $item[$params['sort']];
|
||||
}
|
||||
asort($sortArray);
|
||||
if (empty($params['options']['direction']) || $params['options']['direction'] == 'asc') {
|
||||
asort($sortArray);
|
||||
} else {
|
||||
arsort($sortArray);
|
||||
}
|
||||
|
||||
foreach ($sortArray as $k => $sortedElement) {
|
||||
$sortArray[$k] = $items[$k];
|
||||
}
|
||||
$items = array();
|
||||
$items = $sortArray;
|
||||
//$items = Set::sort($items, '{n}.' . $params['sort'], $params['direction']);
|
||||
}
|
||||
$items = array_values($items);
|
||||
if (!empty($params['options']['focus'])) {
|
||||
foreach ($items as $k => $item) {
|
||||
if ($item[$focusKey] == $params['options']['focus']) {
|
||||
$params['page'] = 1 + intval(floor($k / $params['limit']));
|
||||
$params['current'] = 1 + ($params['page'] - 1) * 60;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
unset($params['options']['focus']);
|
||||
}
|
||||
array_unshift($items, 'dummy');
|
||||
unset($items[0]);
|
||||
|
|
|
@ -734,6 +734,7 @@ class AppModel extends Model {
|
|||
`uuid` varchar(40) COLLATE utf8_bin DEFAULT NULL,
|
||||
`timestamp` int(11) NOT NULL DEFAULT 0,
|
||||
`object_id` int(11) NOT NULL,
|
||||
`event_id` int(11) NOT NULL,
|
||||
`referenced_id` int(11) NOT NULL,
|
||||
`referenced_type` int(11) NOT NULL DEFAULT 0,
|
||||
`relationship_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
|
||||
|
|
|
@ -1268,6 +1268,7 @@ class Event extends AppModel {
|
|||
if (isset($options['disableSiteAdmin']) && $options['disableSiteAdmin']) $isSiteAdmin = false;
|
||||
$conditionsAttributes = array();
|
||||
$conditionsObjects = array();
|
||||
$conditionsObjectReferences = array();
|
||||
|
||||
if (isset($options['flattenObjects']) && $options['flattenObjects']) {
|
||||
$flattenObjects = true;
|
||||
|
@ -1344,26 +1345,24 @@ class Event extends AppModel {
|
|||
if ($options['to']) $conditions['AND'][] = array('Event.date <=' => $options['to']);
|
||||
if ($options['last']) $conditions['AND'][] = array('Event.publish_timestamp >=' => $options['last']);
|
||||
if ($options['event_uuid']) $conditions['AND'][] = array('Event.uuid' => $options['event_uuid']);
|
||||
|
||||
$softDeletables = array('Attribute', 'Object', 'ObjectReference');
|
||||
if (isset($options['deleted']) && $options['deleted']) {
|
||||
if (!$user['Role']['perm_sync']) {
|
||||
$conditionsAttributes['AND'][] = array(
|
||||
'OR' => array(
|
||||
'(SELECT events.org_id FROM events WHERE events.id = Attribute.event_id)' => $user['org_id'],
|
||||
'Attribute.deleted' => 0
|
||||
)
|
||||
);
|
||||
$conditionsObjects['AND'][] = array(
|
||||
'OR' => array(
|
||||
'(SELECT events.org_id FROM events WHERE events.id = Object.event_id)' => $user['org_id'],
|
||||
'Object.deleted' => 0
|
||||
)
|
||||
);
|
||||
foreach ($softDeletables as $softDeletable) {
|
||||
${'conditions' . $softDeletable . 's'}['AND'][] = array(
|
||||
'OR' => array(
|
||||
'(SELECT events.org_id FROM events WHERE events.id = ' . $softDeletable . '.event_id)' => $user['org_id'],
|
||||
$softDeletable . '.deleted' => 0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$conditionsAttributes['AND']['Attribute.deleted'] = 0;
|
||||
$conditionsObjects['AND']['Object.deleted'] = 0;
|
||||
foreach ($softDeletables as $softDeletable) {
|
||||
${'conditions' . $softDeletable . 's'}['AND'][$softDeletable . '.deleted'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($options['idList'] && !$options['tags']) {
|
||||
$conditions['AND'][] = array('Event.id' => $options['idList']);
|
||||
}
|
||||
|
@ -1446,7 +1445,11 @@ class Event extends AppModel {
|
|||
'Object' => array(
|
||||
'fields' => $fieldsObj,
|
||||
'conditions' => $conditionsObjects,
|
||||
'order' => false
|
||||
'order' => false,
|
||||
'ObjectReference' => array(
|
||||
'conditions' => $conditionsObjectReferences,
|
||||
'order' => false
|
||||
)
|
||||
),
|
||||
'ShadowAttribute' => array(
|
||||
'fields' => $fieldsShadowAtt,
|
||||
|
@ -1472,6 +1475,7 @@ class Event extends AppModel {
|
|||
}
|
||||
$results = $this->find('all', $params);
|
||||
if (empty($results)) return array();
|
||||
|
||||
// Do some refactoring with the event
|
||||
$sgsids = $this->SharingGroup->fetchAllAuthorised($user);
|
||||
if (Configure::read('Plugin.Sightings_enable') !== false) {
|
||||
|
@ -1479,6 +1483,29 @@ class Event extends AppModel {
|
|||
}
|
||||
$userEmails = array();
|
||||
foreach ($results as $eventKey => &$event) {
|
||||
if (!empty($event['Object'])) {
|
||||
foreach ($event['Object'] as $k => $object) {
|
||||
if (!empty($object['ObjectReference'])) {
|
||||
foreach ($object['ObjectReference'] as $k2 => $reference) {
|
||||
$type = array('Attribute', 'Object')[$reference['referenced_type']];
|
||||
$temp = $this->{$type}->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('distribution', 'sharing_group_id', 'uuid'),
|
||||
'conditions' => array('id' => $reference['referenced_id'])
|
||||
));
|
||||
if (!empty($temp)) {
|
||||
if (!$isSiteAdmin && $user['User']['org_id'] != $event['Event']['orgc_id']) {
|
||||
if ($temp[$type]['distribution'] == 0 || ($temp[$type]['distribution'] == 4 && !in_array($temp[$type]['sharing_group_id'], $sgsids))) {
|
||||
unset($object['ObjectReference'][$k2]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$event['Object'][$k]['ObjectReference'][$k2][$type] = $temp[$type];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$options['sgReferenceOnly'] && $event['Event']['sharing_group_id']) {
|
||||
$event['SharingGroup'] = $sharingGroupData[$event['Event']['sharing_group_id']]['SharingGroup'];
|
||||
}
|
||||
|
|
|
@ -12,9 +12,41 @@ class ObjectReference extends AppModel {
|
|||
);
|
||||
|
||||
public $belongsTo = array(
|
||||
'MispObject' => array(
|
||||
'className' => 'MispObject',
|
||||
'foreignKey' => 'object_id'
|
||||
),
|
||||
'ReferencedObject' => array(
|
||||
'className' => 'MispObject',
|
||||
'foreignKey' => false,
|
||||
'conditions' => array(
|
||||
'ReferencedObject.id' => 'ObjectReference.referenced_id',
|
||||
1 => 'ObjectReference.referenced_type'
|
||||
),
|
||||
),
|
||||
'ReferencedAttribute' => array(
|
||||
'className' => 'Attribute',
|
||||
'foreignKey' => false,
|
||||
'conditions' => array(
|
||||
'ReferencedAttribute.id' => 'ObjectReference.referenced_id',
|
||||
0 => 'ObjectReference.referenced_type'
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
public $validate = array(
|
||||
);
|
||||
|
||||
|
||||
public function beforeValidate($options = array()) {
|
||||
parent::beforeValidate();
|
||||
if (empty($this->data['ObjectReference']['uuid'])) {
|
||||
$this->data['ObjectReference']['uuid'] = CakeText::uuid();
|
||||
}
|
||||
$date = date('Y-m-d H:i:s');
|
||||
$this->data['Organisation']['timestamp'] = $date;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
$tr_class = '';
|
||||
$linkClass = 'white';
|
||||
$linkClass = 'blue';
|
||||
$otherColour = 'blue';
|
||||
if (!empty($child)) {
|
||||
if ($child === 'last' && empty($object['ShadowAttribute'])) {
|
||||
|
@ -20,8 +20,11 @@
|
|||
if (!empty($object['deleted'])) {
|
||||
$tr_class .= ' deleted-attribute';
|
||||
}
|
||||
if (!empty($k)) {
|
||||
$tr_class .= ' row_' . h($k);
|
||||
}
|
||||
?>
|
||||
<tr id = "Attribute_<?php echo h($object['id']); ?>_tr" class="<?php echo $tr_class; ?>">
|
||||
<tr id = "Attribute_<?php echo h($object['id']); ?>_tr" class="<?php echo $tr_class; ?>" tabindex="0">
|
||||
<?php
|
||||
if ($mayModify):
|
||||
?>
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
$tr_class = 'tableHighlightBorderTop borderBlue';
|
||||
if ($object['deleted']) $tr_class .= ' lightBlueRow';
|
||||
else $tr_class .= ' blueRow';
|
||||
if (!empty($k)) {
|
||||
$tr_class .= ' row_' . h($k);
|
||||
}
|
||||
?>
|
||||
<tr id = "Object_<?php echo $object['id']; ?>_tr" class="<?php echo $tr_class; ?>">
|
||||
<tr id = "Object_<?php echo $object['id']; ?>_tr" class="<?php echo $tr_class; ?>" tabindex="0">
|
||||
<?php
|
||||
if ($mayModify):
|
||||
?>
|
||||
|
@ -27,13 +30,33 @@
|
|||
</td>
|
||||
<td colspan="<?php echo $fieldCount -5;?>">
|
||||
<span class="bold">Name: </span><?php echo h($object['name']);?>
|
||||
<span class="fa fa-expand" title="Expand or Collapse" role="button" tabindex="0" aria-label="Expand or Collapse" data-toggle="collapse" data-target="#Object_<?php echo $object['id']; ?>_collapsible"></span>
|
||||
<span class="fa fa-expand useCursorPointer" title="Expand or Collapse" role="button" tabindex="0" aria-label="Expand or Collapse" data-toggle="collapse" data-target="#Object_<?php echo h($object['id']); ?>_collapsible"></span>
|
||||
<br />
|
||||
<div id="Object_<?php echo $object['id']; ?>_collapsible" class="collapse">
|
||||
<span class="bold">Meta-category: </span><?php echo h($object['meta-category']);?><br />
|
||||
<span class="bold">Description: </span><?php echo h($object['description']);?><br />
|
||||
<span class="bold">Tempate: </span><?php echo h($object['name']) . ' v' . h($object['template_version']) . ' (' . h($object['template_uuid']) . ')'; ?>
|
||||
</div>
|
||||
<span class="bold">References: </span>
|
||||
<?php
|
||||
echo count($object['ObjectReference']);
|
||||
if (!empty($object['ObjectReference'])):
|
||||
?>
|
||||
<span class="fa fa-expand useCursorPointer" title="Expand or Collapse" role="button" tabindex="0" aria-label="Expand or Collapse" data-toggle="collapse" data-target="#Object_<?php echo h($object['id']); ?>_references_collapsible"></span>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<span class="fa fa-plus-square useCursorPointer" title="Add reference" role="button" tabindex="0" aria-label="Add reference" onClick="genericPopup('<?php echo '/objectReferences/add/' . h($object['id']);?>', '#popover_form');"></span>
|
||||
<div id="Object_<?php echo $object['id']; ?>_references_collapsible" class="collapse">
|
||||
<?php
|
||||
foreach ($object['ObjectReference'] as $reference):
|
||||
$uuid = empty($reference['Object']) ? $reference['Attribute']['uuid'] : $reference['Object']['uuid'];
|
||||
?>
|
||||
<a class="bold white useCursorPointer" onClick="pivotObjectReferences('<?php echo h($currentUri); ?>', '<?php echo $uuid; ?>')"><?php echo array('Attribute', 'Object')[$reference['referenced_type']] . ': ' . h($reference['relationship_type']);?></a><br />
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="shortish">
|
||||
<?php
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
$tr_class .= ' tableHighlightBorder borderOrange';
|
||||
}
|
||||
}
|
||||
$identifier = (empty($k)) ? '' : ' id="row_' . h($k) . '" tabindex="0"';
|
||||
?>
|
||||
<tr id = "proposal<?php echo '_' . $object['id'] . '_tr'; ?>" class="<?php echo $tr_class; ?>">
|
||||
<tr id = "proposal<?php echo '_' . $object['id'] . '_tr'; ?>" class="<?php echo $tr_class; ?>" <?php echo $identifier; ?>>
|
||||
<?php if ($mayModify): ?>
|
||||
<td style="width:10px;" data-position="<?php echo h($object['objectType']) . '_' . h($object['id']); ?>">
|
||||
<input id = "select_proposal_<?php echo $object['id']; ?>" class="select_proposal row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" />
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
$tr_class .= ' tableHighlightBorder borderOrange';
|
||||
}
|
||||
}
|
||||
$identifier = (empty($k)) ? '' : ' id="row_' . h($k) . '" tabindex="0"';
|
||||
?>
|
||||
<tr id = "<?php echo $currentType . '_' . $object['id'] . '_tr'; ?>" class="<?php echo $tr_class; ?>">
|
||||
<tr id = "<?php echo $currentType . '_' . $object['id'] . '_tr'; ?>" class="<?php echo $tr_class; ?>" <?php echo $identifier; ?>>
|
||||
<?php
|
||||
if ($mayModify):
|
||||
?>
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
<div class="pagination">
|
||||
<ul>
|
||||
<?php
|
||||
$url = array_merge(array('controller' => 'events', 'action' => 'viewEventAttributes', $event['Event']['id']), $this->request->named);
|
||||
$params = $this->request->named;
|
||||
unset($params['focus']);
|
||||
$url = array_merge(array('controller' => 'events', 'action' => 'viewEventAttributes', $event['Event']['id']), $params);
|
||||
$this->Paginator->options(array(
|
||||
'url' => $url,
|
||||
'update' => '#attributes_div',
|
||||
|
@ -181,6 +183,7 @@
|
|||
2 => 'proposal_delete',
|
||||
3 => 'object'
|
||||
);
|
||||
$focusedRow = false;
|
||||
foreach ($event['objects'] as $k => $object) {
|
||||
$insertBlank = false;
|
||||
echo $this->element('/Events/View/row_' . $object['objectType'], array(
|
||||
|
@ -191,6 +194,9 @@
|
|||
'page' => $page,
|
||||
'fieldCount' => $fieldCount
|
||||
));
|
||||
if (!empty($focus) && ($object['objectType'] == 'object' || $object['objectType'] == 'attribute') && $object['uuid'] == $focus) {
|
||||
$focusedRow = $k;
|
||||
}
|
||||
if (
|
||||
($object['objectType'] == 'attribute' && !empty($object['ShadowAttribute'])) ||
|
||||
$object['objectType'] == 'object'
|
||||
|
@ -221,7 +227,6 @@ attributes or the appropriate distribution level. If you think there is a mistak
|
|||
<div class="pagination">
|
||||
<ul>
|
||||
<?php
|
||||
$url = array_merge(array('controller' => 'events', 'action' => 'viewEventAttributes', $event['Event']['id']), $this->request->named);
|
||||
$this->Paginator->options(array(
|
||||
'url' => $url,
|
||||
'update' => '#attributes_div',
|
||||
|
@ -253,6 +258,17 @@ attributes or the appropriate distribution level. If you think there is a mistak
|
|||
var lastSelected = false;
|
||||
var deleted = <?php echo (isset($deleted) && $deleted) ? 'true' : 'false';?>;
|
||||
$(document).ready(function() {
|
||||
<?php
|
||||
if ($focusedRow !== false):
|
||||
?>
|
||||
//window.location.hash = '.row_' + '<?php echo h($focusedRow); ?>';
|
||||
console.log('.row_' + '<?php echo h($focusedRow); ?>');
|
||||
//$.scrollTo('#row_' + '<?php echo h($k); ?>', 800, {easing:'elasout'});
|
||||
//$('html,body').animate({scrollTop: $('#row_' + '<?php echo h($k); ?>').offset().top}, 'slow');
|
||||
$('.row_' + '<?php echo h($focusedRow); ?>').focus();
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
setContextFields();
|
||||
popoverStartup();
|
||||
$('.select_attribute').removeAttr('checked');
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<div class="popover_choice">
|
||||
<?php echo $this->Form->create('ObjectReference', array('url' => '/objectReferences/add/' + $objectId));?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Add Object Reference'); ?></legend>
|
||||
<div class="overlay_spacing">
|
||||
<div class="row-fluid">
|
||||
<div class="span6">
|
||||
<?php
|
||||
echo $this->Form->input('relationship_type', array(
|
||||
'label' => 'Relationship type',
|
||||
'style' => 'width:320px;'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<?php
|
||||
echo $this->Form->input('comment', array(
|
||||
'label' => 'Comment',
|
||||
'rows' => 1,
|
||||
'style' => 'width:320px;height:20px !important;'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input clear"></div>
|
||||
<div class="row-fluid">
|
||||
<div class="span6">
|
||||
<?php
|
||||
echo $this->Form->input('uuid', array(
|
||||
'label' => 'Target UUID',
|
||||
'div' => false,
|
||||
'style' => 'width:320px;'
|
||||
));
|
||||
?>
|
||||
<br />
|
||||
<select id="targetSelect" multiple="multiple" style="width:100%;height:200px;">
|
||||
<?php
|
||||
if (!empty($event['Object'])):
|
||||
foreach ($event['Object'] as $object):
|
||||
?>
|
||||
<option class="selectOption" value="<?php echo h($object['uuid']);?>" data-type="Object">Object: <?php echo h($object['meta-category']) . '/' . h($object['name']); ?></option>
|
||||
<?php
|
||||
endforeach;
|
||||
endif;
|
||||
if (!empty($event['Attribute'])):
|
||||
foreach ($event['Attribute'] as $attribute):
|
||||
?>
|
||||
<option class="selectOption" value="<?php echo h($attribute['uuid']);?>" data-type="Attribute">Attribute: <?php echo h($attribute['category']) . '/' . h($attribute['type']); ?></option>
|
||||
<?php
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<label for="selectedData">Target Details</label>
|
||||
<div class="redHighlightedBlock" id="targetData">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<table style="margin-bottom:5px;">
|
||||
<tr>
|
||||
<td>
|
||||
<span id="submitButton" class="btn btn-primary" title="Submit" role="button" tabindex="0" aria-label="Submit" onClick="submitPopoverForm('<?php echo h($objectId); ?>', 'addObjectReference')">Submit</span>
|
||||
</td>
|
||||
<td style="width:100%;"> </td>
|
||||
<td>
|
||||
<span class="btn btn-inverse" title="Cancel" role="button" tabindex="0" aria-label="Cancel" onClick="cancelPopoverForm();">Cancel</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var targetEvent = <?php echo json_encode($event); ?>;
|
||||
$(document).ready(function() {
|
||||
$('#ObjectReferenceUuid').on('input', function() {
|
||||
objectReferenceInput();
|
||||
});
|
||||
$(".selectOption").click(function() {
|
||||
changeObjectReferenceSelectOption();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php echo $this->Js->writeBuffer(); // Write cached scripts
|
|
@ -74,7 +74,7 @@
|
|||
</dl>
|
||||
</div>
|
||||
<?php
|
||||
if ($template['warnings']):
|
||||
if (!empty($template['warnings'])):
|
||||
?>
|
||||
<span class="red bold">Warning, issues found with the template:</span>
|
||||
<div class="red">
|
||||
|
@ -121,7 +121,6 @@
|
|||
'label' => false,
|
||||
'div' => false
|
||||
);
|
||||
if ($action == 'edit') unset($formSettings['value']);
|
||||
echo $this->Form->input('Attribute.' . $k . '.object_relation', $formSettings);
|
||||
if ($action == 'edit') {
|
||||
echo $this->Form->input('Attribute.' . $k . '.uuid', array(
|
||||
|
@ -136,7 +135,6 @@
|
|||
'label' => false,
|
||||
'div' => false
|
||||
);
|
||||
if ($action == 'edit') unset($formSettings['value']);
|
||||
echo $this->Form->input('Attribute.' . $k . '.type', $formSettings);
|
||||
echo '<span class="bold">' . Inflector::humanize(h($element['in-object-name'])) . '</span>';
|
||||
if (!empty($template['ObjectTemplate']['requirements']['required']) && in_array($element['in-object-name'], $template['ObjectTemplate']['requirements']['required'])) {
|
||||
|
@ -154,7 +152,6 @@
|
|||
'label' => false,
|
||||
'div' => false
|
||||
);
|
||||
if ($action == 'edit') unset($formSettings['value']);
|
||||
echo $this->Form->input('Attribute.' . $k . '.category', $formSettings);
|
||||
?>
|
||||
</td>
|
||||
|
|
|
@ -1610,6 +1610,20 @@ a.discrete {
|
|||
border-radius:5px;
|
||||
}
|
||||
|
||||
.redHighlightedBlock {
|
||||
border:1px solid red;
|
||||
background-color:white;
|
||||
padding:5px;
|
||||
border-radius:5px;
|
||||
height:228px;
|
||||
overflow-y:scroll;
|
||||
line-height:12px;
|
||||
}
|
||||
|
||||
.indent {
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
white-space:pre-wrap !important;
|
||||
}
|
||||
|
|
|
@ -877,6 +877,9 @@ function submitPopoverForm(context_id, referer, update_context_id) {
|
|||
url = "/sightings/add/" + context_id;
|
||||
closePopover = false;
|
||||
break;
|
||||
case 'addObjectReference':
|
||||
url = "/objectReferences/add/" + context_id;
|
||||
break;
|
||||
}
|
||||
if (url !== null) {
|
||||
$.ajax({
|
||||
|
@ -902,7 +905,7 @@ function submitPopoverForm(context_id, referer, update_context_id) {
|
|||
$('#sightingsListAllToggle').removeClass('btn-inverse');
|
||||
$('#sightingsListAllToggle').addClass('btn-primary');
|
||||
}
|
||||
if (context == 'event' && (referer == 'add' || referer == 'massEdit' || referer == 'replaceAttributes')) eventUnpublish();
|
||||
if (context == 'event' && (referer == 'add' || referer == 'massEdit' || referer == 'replaceAttributes' || referer == 'addObjectReference')) eventUnpublish();
|
||||
$(".loading").hide();
|
||||
},
|
||||
type:"post",
|
||||
|
@ -2560,6 +2563,25 @@ function filterAttributes(filter, id) {
|
|||
});
|
||||
}
|
||||
|
||||
function pivotObjectReferences(url, uuid) {
|
||||
url += '/focus:' + uuid;
|
||||
console.log(url);
|
||||
$.ajax({
|
||||
type:"get",
|
||||
url:url,
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data) {
|
||||
$("#attributes_div").html(data);
|
||||
$(".loading").hide();
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Something went wrong - could not fetch attributes.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleDeletedAttributes(url) {
|
||||
url = url.replace(/view\//i, 'viewEventAttributes/');
|
||||
if (url.indexOf('deleted:') > -1) {
|
||||
|
@ -3090,23 +3112,75 @@ function checkAndEnableCheckbox(id, enable) {
|
|||
}
|
||||
}
|
||||
|
||||
function enableDisableObjectRows(rows) {
|
||||
rows.forEach(function(i) {
|
||||
if ($("#Attribute" + i + "ValueSelect").length != 0) {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", true);
|
||||
} else if ($("#Attribute" + i + "Attachment").length != 0) {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $("#Attribute" + i + "Attachment").val() != "");
|
||||
} else {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $("#Attribute" + i + "Value").val() != "");
|
||||
}
|
||||
$("#Attribute" + i + "Value").bind('input propertychange', function() {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $(this).val() != "");
|
||||
});
|
||||
$("#Attribute" + i + "Attachment").on('change', function() {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $("#Attribute" + i + "Attachment").val() != "");
|
||||
});
|
||||
function enableDisableObjectRows(rows) {
|
||||
rows.forEach(function(i) {
|
||||
if ($("#Attribute" + i + "ValueSelect").length != 0) {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", true);
|
||||
} else if ($("#Attribute" + i + "Attachment").length != 0) {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $("#Attribute" + i + "Attachment").val() != "");
|
||||
} else {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $("#Attribute" + i + "Value").val() != "");
|
||||
}
|
||||
$("#Attribute" + i + "Value").bind('input propertychange', function() {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $(this).val() != "");
|
||||
});
|
||||
$("#Attribute" + i + "Attachment").on('change', function() {
|
||||
checkAndEnableCheckbox("#Attribute" + i + "Save", $("#Attribute" + i + "Attachment").val() != "");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function objectReferenceInput() {
|
||||
var types = ["Attribute", "Object"];
|
||||
for (var type in types) {
|
||||
for (var k in targetEvent[types[type]]) {
|
||||
if (targetEvent[types[type]][k]['uuid'] == $('#ObjectReferenceUuid').val()) {
|
||||
$('#targetSelect').val($('#ObjectReferenceUuid').val());
|
||||
changeObjectReferenceSelectOption();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function changeObjectReferenceSelectOption() {
|
||||
var object = $('#targetSelect option:selected');
|
||||
var uuid = $(object).val();
|
||||
$('#ObjectReferenceUuid').val(uuid);
|
||||
var type = $(object).data('type');
|
||||
if (type == "Attribute") {
|
||||
$('#targetData').html("");
|
||||
for (var k in targetEvent[type][uuid]) {
|
||||
if ($.inArray(k, ['uuid', 'category', 'type', 'value', 'to_ids']) !== -1) {
|
||||
$('#targetData').append('<div><span id="' + uuid + '_' + k + '_key" class="bold"></span>: <span id="' + uuid + '_' + k + '_data"></span></div>');
|
||||
$('#' + uuid + '_' + k + '_key').text(k);
|
||||
$('#' + uuid + '_' + k + '_data').text(targetEvent[type][uuid][k]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$('#targetData').html("");
|
||||
for (var k in targetEvent[type][uuid]) {
|
||||
if (k == 'Attribute') {
|
||||
$('#targetData').append('<br /><div><span id="header" class="bold">Attributes:</span>');
|
||||
for (attribute in targetEvent[type][uuid]['Attribute']) {
|
||||
for (k2 in targetEvent[type][uuid]['Attribute'][attribute]) {
|
||||
if ($.inArray(k2, ['category', 'type', 'value', 'to_ids']) !== -1) {
|
||||
$('#targetData').append('<div class="indent"><span id="' + targetEvent[type][uuid]['Attribute'][attribute]['uuid'] + '_' + k2 + '_key" class="bold"></span>: <span id="' + targetEvent[type][uuid]['Attribute'][attribute]['uuid'] + '_' + k2 + '_data"></span></div>');
|
||||
$('#' + targetEvent[type][uuid]['Attribute'][attribute]['uuid'] + '_' + k2 + '_key').text(k2);
|
||||
$('#' + targetEvent[type][uuid]['Attribute'][attribute]['uuid'] + '_' + k2 + '_data').text(targetEvent[type][uuid]['Attribute'][attribute][k2]);
|
||||
}
|
||||
}
|
||||
$('#targetData').append('<br />');
|
||||
}
|
||||
} else {
|
||||
if ($.inArray(k, ['name', 'uuid', 'meta-category']) !== -1) {
|
||||
$('#targetData').append('<div><span id="' + uuid + '_' + k + '_key" class="bold"></span>: <span id="' + uuid + '_' + k + '_data"></span></div>');
|
||||
$('#' + uuid + '_' + k + '_key').text(k);
|
||||
$('#' + uuid + '_' + k + '_data').text(targetEvent[type][uuid][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(function(){
|
||||
"use strict";
|
||||
|
|
Loading…
Reference in New Issue