new: Added first iteration of object references and other changes

- various fixes
- rework of the pagination library
pull/2489/head
iglocska 2017-08-09 17:53:25 +02:00
parent 94fbfed48f
commit 0e7dd2eddc
17 changed files with 521 additions and 52 deletions

View File

@ -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,

View File

@ -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) {

View File

@ -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) {
}
}

View File

@ -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

View File

@ -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]);

View File

@ -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,

View File

@ -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'];
}

View File

@ -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;
}
}

View File

@ -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):
?>

View File

@ -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'];
?>
&nbsp;&nbsp;<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

View File

@ -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'];?>" />

View File

@ -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):
?>

View File

@ -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');

View File

@ -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">
&nbsp;
</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%;">&nbsp;</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

View File

@ -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>

View File

@ -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;
}

View File

@ -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";