mirror of https://github.com/MISP/MISP
First version of the sightings
- add / delete sightings via REST - add sightings via the UI - View sightings info on an event and attribute level (event view only for now) - differentiate between own sightings and that of other orgs (additional information via popover still coming) - settings: - 1. enable / disable sightings server wide - 2. set sightings policy - a. Only Event owner can see sightings + everyone sees what they themeselves contribute - b. Anyone that contributes sightings to an event can see the sightings data - c. Everyone that can see the event can see the sightings - 3. Anonymisisation (in progress, data correctly retrieved in business logic) - a. if true, then only own org + "other" is shown - b. otherwise all orgs that submitted sightings are shown Further improvements needed for version 1 of sightings: - 1. Delete via the interface - 2. View detailed sightings information - 3. Graph the sightings data for the event - 4. Include the Sightings data in the XML/JSON views - 5. View sighting for attribute / event via the APIpull/1092/head
parent
f8f367a996
commit
868d4cdd3f
|
@ -6,26 +6,94 @@ class SightingsController extends AppController {
|
|||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
if (!Configure::read('Plugin.Sightings_enable')) throw new MethodNotAllowedException('This feature is not enabled on this instance.');
|
||||
}
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user van view/page.
|
||||
'order' => array(
|
||||
'Sighting.created' => 'DESC'
|
||||
),
|
||||
'order' => array('Sighting.date_sighting' => 'DESC'),
|
||||
);
|
||||
|
||||
public function index() {
|
||||
}
|
||||
|
||||
public function add() {
|
||||
// takes an attribute ID or UUID
|
||||
public function add($id) {
|
||||
if (!$this->userRole['perm_add']) throw new MethodNotAllowedException('You are not authorised to add sightings data as you don\'t have write access.');
|
||||
if (!$this->request->is('post')) throw new MethodNotAllowedException('This action can only be accessed via a post request.');
|
||||
if (strlen($id) == 36) $conditions = array('Attribute.uuid' => $id);
|
||||
else $conditions = array('Attribute.id' => $id);
|
||||
$attribute = $this->Sighting->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => $conditions));
|
||||
if (empty($attribute)) throw new NotFoundException('Could not add sighting information, invalid attribute.');
|
||||
// normalise the request data if it exists
|
||||
if (isset($this->request->data['request'])) $this->request->data = $this->request->data['request'];
|
||||
if (isset($this->request->data['Sighting'])) $this->request->data = $this->request->data['Sighting'];
|
||||
$attribute = $attribute[0];
|
||||
$this->Sighting->create();
|
||||
$date = date('Y-m-d H:i:s');
|
||||
$sighting = array(
|
||||
'attribute_id' => $attribute['Attribute']['id'],
|
||||
'event_id' => $attribute['Attribute']['event_id'],
|
||||
'org_id' => $this->Auth->user('org_id'),
|
||||
'date_sighting' => isset($this->request->data['date_sighting']) ? $this->request->data['date_sighting'] : $date,
|
||||
);
|
||||
$result = $this->Sighting->save($sighting);
|
||||
if ($this->request->is('ajax')) {
|
||||
if (!$result) {
|
||||
$error_message = 'Could not add the Sighting. Reason: ' . json_encode($this->Sighting->validationErrors);
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $error_message)), 'status' => 200));
|
||||
} else {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Sighting added.')), 'status' => 200));
|
||||
}
|
||||
} else {
|
||||
if (!$result) {
|
||||
$this->set('errors', json_encode($this->Sighting->validatidationErrors));
|
||||
$this->set('name', 'Failed');
|
||||
$this->set('message', 'Could not add the Sighting.');
|
||||
$this->set('_serialize', array('name', 'message', 'errors'));
|
||||
} else {
|
||||
$this->set('name', 'Success');
|
||||
$this->set('message', 'Sighting successfuly added.');
|
||||
$this->set('url', '/sightings/add/' . $id);
|
||||
$this->set('id', $this->Sighting->id);
|
||||
$this->set('_serialize', array('name', 'message', 'url', 'id'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function edit($id) {
|
||||
}
|
||||
|
||||
// takes a sighting ID
|
||||
public function delete($id) {
|
||||
|
||||
}
|
||||
if (!$this->userRole['perm_modify_org']) throw new MethodNotAllowedException('You are not authorised to remove sightings data as you don\'t have permission to modify your organisation\'s data.');
|
||||
if (!$this->request->is('post')) throw new MethodNotAllowedException('This action can only be accessed via a post request.');
|
||||
$sighting = $this->Sighting->find('first', array('conditions' => array('Sighting.id' => $id), 'recursive' => -1));
|
||||
if (empty($sighting)) throw new NotFoundException('Invalid sighting.');
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
if ($sighting['Sighting']['org_id'] != $this->Auth->user('org_id')) throw new NotFoundException('Invalid sighting.');
|
||||
}
|
||||
$result = $this->Sighting->delete($sighting['Sighting']['id']);
|
||||
if (!$result) {
|
||||
$this->set('errors', '');
|
||||
$this->set('name', 'Failed');
|
||||
$this->set('message', 'Could not delete the Sighting.');
|
||||
$this->set('_serialize', array('name', 'message', 'errors'));
|
||||
} else {
|
||||
$this->set('name', 'Success');
|
||||
$this->set('message', 'Sighting successfuly deleted.');
|
||||
$this->set('url', '/sightings/delete/' . $id);
|
||||
$this->set('_serialize', array('name', 'message', 'url'));
|
||||
}
|
||||
}
|
||||
|
||||
public function resetLikeButton($id) {
|
||||
$attribute = $this->Sighting->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => array('Attribute.id' => $id)));
|
||||
if (empty($attribute)) throw new MethodNotAllowedException('Invalid attribute');
|
||||
$this->layout = 'text/default';
|
||||
$this->set('id', $id);
|
||||
$this->autoRender = false;
|
||||
$this->render('/Sightings/ajax/like_button');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,19 @@ class AppModel extends Model {
|
|||
case 'addEventBlacklistsContext':
|
||||
$sql = 'ALTER TABLE `event_blacklists` ADD `event_orgc` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL , ADD `event_info` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, ADD `comment` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ;';
|
||||
break;
|
||||
case 'addSightings':
|
||||
$sql = "CREATE TABLE IF NOT EXISTS `sightings` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`attribute_id` int(11) NOT NULL,
|
||||
`event_id` int(11) NOT NULL,
|
||||
`org_id` int(11) NOT NULL,
|
||||
`date_sighting` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `attribute_id` (`attribute_id`),
|
||||
INDEX `event_id` (`event_id`),
|
||||
INDEX `org_id` (`org_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ;";
|
||||
break;
|
||||
case 'makeAttributeUUIDsUnique':
|
||||
$this->__dropIndex('attributes', 'uuid');
|
||||
$sql = 'ALTER TABLE `attributes` ADD UNIQUE (uuid);';
|
||||
|
|
|
@ -1808,7 +1808,8 @@ class Attribute extends AppModel {
|
|||
if (isset($options['contain'])) $params['contain'] = $options['contain'];
|
||||
if (isset($options['fields'])) $params['fields'] = $options['fields'];
|
||||
if (isset($options['conditions'])) $params['conditions']['AND'][] = $options['conditions'];
|
||||
if (isset($options['order'])) $params['conditions']['AND'][] = $options['order'];
|
||||
if (isset($options['order'])) $params['order'] = $options['order'];
|
||||
else ($params['order'] = array());
|
||||
if (isset($options['group'])) $params['group'] = $options['group'];
|
||||
if (Configure::read('MISP.unpublishedprivate')) $params['conditions']['AND'][] = array('Event.published' => 1);
|
||||
$results = $this->find('all', $params);
|
||||
|
|
|
@ -1178,6 +1178,7 @@ class Event extends AppModel {
|
|||
if (empty($results)) return array();
|
||||
// Do some refactoring with the event
|
||||
$sgsids = $this->SharingGroup->fetchAllAuthorised($user);
|
||||
if (Configure::read('Plugin.Sightings_enable')) $this->Sighting = ClassRegistry::init('Sighting');
|
||||
foreach ($results as $eventKey => &$event) {
|
||||
// unset the empty sharing groups that are created due to the way belongsTo is handled
|
||||
if (isset($event['SharingGroup']['SharingGroupServer'])) {
|
||||
|
@ -1215,6 +1216,9 @@ class Event extends AppModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (Configure::read('Plugin.Sightings_enable')) {
|
||||
$event['Sighting'] = $this->Sighting->attachToEvent($event, $user);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
|
|
@ -640,7 +640,7 @@ class Server extends AppModel {
|
|||
'Plugin' => array(
|
||||
'branch' => 1,
|
||||
'RPZ_policy' => array(
|
||||
'level' => 1,
|
||||
'level' => 2,
|
||||
'description' => 'The default policy action for the values added to the RPZ.',
|
||||
'value' => 0,
|
||||
'errorMessage' => '',
|
||||
|
@ -783,7 +783,32 @@ class Server extends AppModel {
|
|||
'type' => 'string',
|
||||
'afterHook' => 'zmqAfterHook',
|
||||
),
|
||||
|
||||
'Sightings_enable' => array(
|
||||
'level' => 1,
|
||||
'description' => 'Enables or disables the sighting functionality. When enabled, users can use the UI or the appropriate APIs to submit sightings data about indicators.',
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'beforeHook' => 'sightingsBeforeHook',
|
||||
),
|
||||
'Sightings_policy' => array(
|
||||
'level' => 1,
|
||||
'description' => 'This setting defines who will have access to seeing the reported sightings. The default setting is the event owner alone (in addition to everyone seeing their own contribution) with the other options being Sighting reporters (meaning the event owner and anyone that provided sighting data about the event) and Everyone (meaning anyone that has access to seeing the event / attribute).',
|
||||
'value' => 0,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForSightingVisibility',
|
||||
'type' => 'numeric',
|
||||
'options' => array(0 => 'Event Owner', 1 => 'Sighting reporters', 2 => 'Everyone'),
|
||||
),
|
||||
'Sightings_anonymise' => array(
|
||||
'level' => 1,
|
||||
'description' => 'Enabling the anonymisation of sightings will simply aggregate all sightings instead of showing the organisations that have reported a sighting. Users will be able to tell the number of sightings their organisation has submitted and the number of sightings for other organisations',
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
),
|
||||
'debug' => array(
|
||||
'level' => 0,
|
||||
|
@ -1567,6 +1592,20 @@ class Server extends AppModel {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function testForSightingVisibility($value) {
|
||||
$numeric = $this->testforNumeric($value);
|
||||
if ($numeric !== true) return $numeric;
|
||||
if ($value < 0 || $value > 2) return 'Invalid setting, valid range is 0-2 (0 = Event owner, 1 = Sighting reporters, 2 = Everyone.';
|
||||
return true;
|
||||
}
|
||||
|
||||
public function sightingsBeforeHook($setting, $value) {
|
||||
if ($value == true) {
|
||||
$this->updateDatabase('addSightings');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function testForRPZSerial($value) {
|
||||
if ($this->testForEmpty($value) !== true) return $this->testForEmpty($value);
|
||||
if (!preg_match('/^((\$date(\d*)|\d*))$/', $value)) return 'Invalid format.';
|
||||
|
|
|
@ -8,25 +8,69 @@ class Sighting extends AppModel{
|
|||
);
|
||||
|
||||
public $validate = array(
|
||||
'event_uuid' => array(
|
||||
'unique' => array(
|
||||
'rule' => 'isUnique',
|
||||
'message' => 'Event already blacklisted.'
|
||||
),
|
||||
'uuid' => array(
|
||||
'rule' => array('uuid'),
|
||||
'message' => 'Please provide a valid UUID'
|
||||
),
|
||||
)
|
||||
'event_id' => 'numeric',
|
||||
'attribute_id' => 'numeric',
|
||||
'org_id' => 'numeric',
|
||||
'date_sighting' => 'datetime'
|
||||
);
|
||||
|
||||
public $belongsTo = array(
|
||||
'Attribute' => array(
|
||||
'className' => 'Attribute',
|
||||
),
|
||||
'Event' => array(
|
||||
'className' => 'Event',
|
||||
),
|
||||
'Organisation' => array(
|
||||
'className' => 'Organisation',
|
||||
'foreignKey' => 'org_id'
|
||||
),
|
||||
);
|
||||
|
||||
public function beforeValidate($options = array()) {
|
||||
parent::beforeValidate();
|
||||
$date = date('Y-m-d H:i:s');
|
||||
if (empty($this->data['Sighting']['id'])) {
|
||||
$this->data['Sighting']['date_created'] = $date;
|
||||
if (empty($this->data['Sighting']['id']) && empty($this->data['Sighting']['date_sighting'])) {
|
||||
$this->data['Sighting']['date_sighting'] = $date;
|
||||
}
|
||||
$this->data['Sighting']['date_modified'] = $date;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function attachToEvent(&$event, &$user, $eventOnly=false) {
|
||||
$ownEvent = false;
|
||||
if ($user['Role']['perm_site_admin'] || $event['Event']['org_id'] == $user['org_id']) $ownEvent = true;
|
||||
$conditions = array('Sighting.event_id' => $event['Event']['id']);
|
||||
if (!$ownEvent && (!Configure::read('Plugin.Sightings_policy') || Configure::read('Plugin.Sightings_policy') == 0)) $conditions['Sighting.org_id'] = $user['org_id'];
|
||||
$contain = array();
|
||||
if (Configure::read('MISP.showorg')) $contain['Organisation'] = array('fields' => array('Organisation.id', 'Organisation.uuid', 'Organisation.name'));
|
||||
|
||||
// Sighting reporters setting
|
||||
// If the event has any sightings for the user's org, then the user is a sighting reporter for the event too.
|
||||
// This means that he /she has access to the sightings data contained within
|
||||
if (!$ownEvent && Configure::read('Plugin.Sightings_policy') == 1) {
|
||||
$temp = $this->find('first', array('recursive' => -1, 'conditions' => array('Sighting.event_id' => $event['Event']['id'], 'Sighting.org_id' => $user['org_id'])));
|
||||
if (empty($temp)) return array();
|
||||
}
|
||||
|
||||
$sightings = $this->find('all', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'contain' => $contain,
|
||||
));
|
||||
if (empty($sightings)) return array();
|
||||
$anonymise = Configure::read('Plugin.Sightings_anonymise');
|
||||
|
||||
foreach ($sightings as $k => &$sighting) {
|
||||
if ($anonymise && !$user['Role']['perm_site_admin']) {
|
||||
if ($sighting['Sighting']['org_id'] != $user['org_id']) {
|
||||
unset($sightings[$k]['Sighting']['org_id']);
|
||||
unset($sightings[$k]['Organisation']);
|
||||
}
|
||||
}
|
||||
//rearrange it to match the event format of fetchevent
|
||||
if (isset($sightings[$k]['Organisation'])) $sightings[$k]['Sighting']['Organisation'] = $sightings[$k]['Organisation'];
|
||||
$sightings[$k] = $sightings[$k]['Sighting'] ;
|
||||
}
|
||||
return $sightings;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,25 @@
|
|||
$possibleAction = 'Proposal';
|
||||
if ($mayModify) $possibleAction = 'Attribute';
|
||||
$all = false;
|
||||
if (isset($this->params->params['paging']['Event']['page']) && $this->params->params['paging']['Event']['page'] == 0) $all = true;
|
||||
if (isset($this->params->params['paging']['Event']['page'])) {
|
||||
if ($this->params->params['paging']['Event']['page'] == 0) $all = true;
|
||||
$page = $this->params->params['paging']['Event']['page'];
|
||||
} else {
|
||||
$page = 0;
|
||||
}
|
||||
if (Configure::read('Plugin.Sightings_enable')) {
|
||||
$attributeSightings = array();
|
||||
$attributeOwnSightings = array();
|
||||
if (isset($event['Sighting']) && !empty($event['Sighting'])) {
|
||||
foreach ($event['Sighting'] as $sighting) {
|
||||
$attributeSightings[$sighting['attribute_id']][] = $sighting;
|
||||
if (isset($sighting['org_id']) && $sighting['org_id'] == $me['org_id']) {
|
||||
if (isset($attributeOwnSightings[$sighting['attribute_id']])) $attributeOwnSightings[$sighting['attribute_id']]++;
|
||||
else $attributeOwnSightings[$sighting['attribute_id']] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
|
@ -94,6 +112,7 @@
|
|||
<th>Related Events</th>
|
||||
<th title="<?php echo $attrDescriptions['signature']['desc'];?>"><?php echo $this->Paginator->sort('to_ids', 'IDS');?></th>
|
||||
<th title="<?php echo $attrDescriptions['distribution']['desc'];?>"><?php echo $this->Paginator->sort('distribution');?></th>
|
||||
<?php if (Configure::read('Plugin.Sightings_enable'))?><th>Sightings</th>
|
||||
<th class="actions">Actions</th>
|
||||
</tr>
|
||||
<?php
|
||||
|
@ -260,6 +279,25 @@
|
|||
?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
endif;
|
||||
if (Configure::read('Plugin.Sightings_enable')):
|
||||
?>
|
||||
<td class="short <?php echo $extra;?>">
|
||||
<span id="sightingForm_<?php echo h($object['id']);?>">
|
||||
<?php
|
||||
if($object['objectType'] == 0):
|
||||
echo $this->Form->create('Sighting', array('id' => 'Sighting_' . $object['id'], 'url' => '/sightings/add/' . $object['id'], 'style' => 'display:none;'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</span>
|
||||
<span class="icon-thumbs-up useCursorPointer" onClick="addSighting('<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');"> </span>
|
||||
<span id="sightingCount_<?php echo h($object['id']); ?>" class="bold sightingsCounter_<?php echo h($object['id']); ?>"><?php echo (!empty($attributeSightings[$object['id']]) ? count($attributeSightings[$object['id']]) : 0); ?></span>
|
||||
(<span id="ownSightingCount_<?php echo h($object['id']); ?>" class="bold green sightingsCounter_<?php echo h($object['id']); ?>"><?php echo (isset($attributeOwnSightings[$object['id']]) ? $attributeOwnSightings[$object['id']] : 0); ?></span>)
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
</td>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
<?php
|
||||
$mayModify = (($isAclModify && $event['Event']['user_id'] == $me['id'] && $event['Orgc']['id'] == $me['org_id']) || ($isAclModifyOrg && $event['Orgc']['id'] == $me['org_id']));
|
||||
$mayPublish = ($isAclPublish && $event['Orgc']['id'] == $me['org_id']);
|
||||
if (Configure::read('Plugin.Sightings_enable')) {
|
||||
if (isset($event['Sighting']) && !empty($event['Sighting'])) {
|
||||
$ownSightings = array();
|
||||
foreach ($event['Sighting'] as $sighting) {
|
||||
if (isset($sighting['org_id']) && $sighting['org_id'] == $me['org_id']) $ownSightings[] = $sighting;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'event', 'menuItem' => 'viewEvent', 'mayModify' => $mayModify, 'mayPublish' => $mayPublish));
|
||||
|
@ -126,26 +134,27 @@ $mayPublish = ($isAclPublish && $event['Orgc']['id'] == $me['org_id']);
|
|||
|
||||
</dd>
|
||||
<?php
|
||||
$published = '';
|
||||
$notPublished = 'style="display:none;"';
|
||||
if ($event['Event']['published'] == 0) {
|
||||
$published = 'style="display:none;"';
|
||||
$notPublished = '';
|
||||
$dtclass='published';
|
||||
$ddclass='published green';
|
||||
if (!$event['Event']['published']) {
|
||||
if ($isAclPublish) {
|
||||
$dtclass = $ddclass = 'visibleDL notPublished';
|
||||
} else {
|
||||
$dtclass = 'notPublished';
|
||||
$ddclass = 'nobPublished red';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<dt class="published" <?php echo $published;?>>Published</dt>
|
||||
<dd class="published green" <?php echo $published;?>>Yes</dd>
|
||||
<?php
|
||||
if ($isAclPublish) :
|
||||
?>
|
||||
<dt class="visibleDL notPublished" <?php echo $notPublished;?>>Published</dt>
|
||||
<dd class="visibleDL notPublished" <?php echo $notPublished;?>>No</dd>
|
||||
<?php
|
||||
else:
|
||||
?>
|
||||
<dt class="notPublished" <?php echo $notPublished;?>>Published</dt>
|
||||
<dd class="notPublished red" <?php echo $notPublished;?>>No</dd>
|
||||
<?php endif; ?>
|
||||
<dt class="<?php echo $dtclass;?>">Published</dt>
|
||||
<dd class="<?php echo $ddclass;?>"><?php echo ($event['Event']['published'] ? 'Yes' : 'No');?></dd>
|
||||
<?php if (Configure::read('Plugin.Sightings_enable')): ?>
|
||||
<dt>Sightings</dt>
|
||||
<dd style="word-wrap: break-word;">
|
||||
<span id="eventSightingCount" class="bold sightingsCounter"><?php echo count($event['Sighting']); ?></span>
|
||||
(<span id="eventOwnSightingCount" class="green bold sightingsCounter"><?php echo isset($ownSightings) ? count($ownSightings) : 0; ?></span>)
|
||||
<?php if(!Configure::read('Plugin.Sightings_policy')) echo '- restricted to own organisation only.'?>
|
||||
</dd>
|
||||
<?php endif;?>
|
||||
</dl>
|
||||
</div>
|
||||
<?php if (!empty($event['RelatedEvent'])):?>
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
echo $this->Form->create('Sighting', array('id' => 'Sighting_' . $id, 'url' => '/sightings/add/' . $id, 'style' => 'display:none;'));
|
||||
echo $this->Form->end();
|
||||
?>
|
|
@ -236,6 +236,29 @@ function postActivationScripts(name, type, id, field, event) {
|
|||
$(name + '_solid').hide();
|
||||
}
|
||||
|
||||
function addSighting(attribute_id, event_id, $page) {
|
||||
$.ajax({
|
||||
data: $('#Sighting_' + attribute_id).closest("form").serialize(),
|
||||
cache: false,
|
||||
success:function (data, textStatus) {
|
||||
handleGenericAjaxResponse(data);
|
||||
var result = JSON.parse(data);
|
||||
if (result.saved == true) {
|
||||
$('.sightingsCounter').each(function( counter ) {
|
||||
$(this).html(parseInt($(this).html()) + 1);
|
||||
});
|
||||
updateIndex(event_id, 'event');
|
||||
}
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Request failed for an unknown reason.');
|
||||
updateIndex(context, 'event');
|
||||
},
|
||||
type:"post",
|
||||
url:"/sightings/add/" + attribute_id
|
||||
});
|
||||
}
|
||||
|
||||
function resetForms() {
|
||||
$('.inline-field-solid').show();
|
||||
$('.inline-field-placeholder').empty();
|
||||
|
|
Loading…
Reference in New Issue