mirror of https://github.com/MISP/MISP
Merge branch 'develop' of github.com:MISP/MISP into develop
commit
fcc1996a2e
|
@ -1257,7 +1257,7 @@ class AttributesController extends AppController
|
|||
// tags to remove
|
||||
$tags = $this->Attribute->AttributeTag->getAttributesTags($attributes);
|
||||
$tagItemsRemove = array();
|
||||
foreach ($tags as $k => $tag) {
|
||||
foreach ($tags as $tag) {
|
||||
$tagName = $tag['name'];
|
||||
$tagItemsRemove[] = array(
|
||||
'name' => $tagName,
|
||||
|
@ -1275,9 +1275,9 @@ class AttributesController extends AppController
|
|||
unset($tags);
|
||||
|
||||
// clusters to remove
|
||||
$clusters = $this->Attribute->AttributeTag->getAttributesClusters($attributes);
|
||||
$clusters = $this->Attribute->AttributeTag->getAttributesClusters($this->Auth->user(), $attributes);
|
||||
$clusterItemsRemove = array();
|
||||
foreach ($clusters as $k => $cluster) {
|
||||
foreach ($clusters as $cluster) {
|
||||
$name = $cluster['value'];
|
||||
$optionName = $cluster['value'];
|
||||
$synom = $cluster['synonyms_string'] !== '' ? " ({$cluster['synonyms_string']})" : '';
|
||||
|
@ -1304,7 +1304,7 @@ class AttributesController extends AppController
|
|||
'conditions' => array('published' => true)
|
||||
));
|
||||
$clusterItemsAdd = array();
|
||||
foreach ($clusters as $k => $cluster) {
|
||||
foreach ($clusters as $cluster) {
|
||||
$clusterItemsAdd[] = array(
|
||||
'name' => $cluster['GalaxyCluster']['value'],
|
||||
'value' => $cluster['GalaxyCluster']['id']
|
||||
|
@ -1346,6 +1346,7 @@ class AttributesController extends AppController
|
|||
$this->set('clusterItemsRemove', $clusterItemsRemove);
|
||||
$this->set('options', array( // set chosen (select picker) options
|
||||
'multiple' => -1,
|
||||
'autofocus' => false,
|
||||
'disabledSubmitButton' => true,
|
||||
'flag_redraw_chosen' => true,
|
||||
'select_options' => array(
|
||||
|
|
|
@ -1159,7 +1159,17 @@ class EventsController extends AppController
|
|||
$this->set('includeDecayScore', 0);
|
||||
}
|
||||
|
||||
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
|
||||
// Site admin can view event as different user
|
||||
if ($this->_isSiteAdmin() && isset($this->params['named']['viewAs'])) {
|
||||
$user = $this->User->getAuthUser($this->params['named']['viewAs']);
|
||||
if (empty($user)) {
|
||||
throw new NotFoundException(__("User not found"));
|
||||
}
|
||||
} else {
|
||||
$user = $this->Auth->user();
|
||||
}
|
||||
|
||||
$results = $this->Event->fetchEvent($user, $conditions);
|
||||
if (empty($results)) {
|
||||
throw new NotFoundException(__('Invalid event'));
|
||||
}
|
||||
|
@ -1308,11 +1318,12 @@ class EventsController extends AppController
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $user
|
||||
* @param array $event
|
||||
* @param bool $continue
|
||||
* @param int $fromEvent
|
||||
*/
|
||||
private function __viewUI($event, $continue, $fromEvent)
|
||||
private function __viewUI(array $user, $event, $continue, $fromEvent)
|
||||
{
|
||||
$this->loadModel('Taxonomy');
|
||||
$filterData = array(
|
||||
|
@ -1346,7 +1357,7 @@ class EventsController extends AppController
|
|||
// set the data for the contributors / history field
|
||||
$contributors = $this->Event->ShadowAttribute->getEventContributors($event['Event']['id']);
|
||||
$this->set('contributors', $contributors);
|
||||
if ($this->userRole['perm_publish'] && $event['Event']['orgc_id'] == $this->Auth->user('org_id')) {
|
||||
if ($user['Role']['perm_publish'] && $event['Event']['orgc_id'] == $user['org_id']) {
|
||||
$proposalStatus = false;
|
||||
if (isset($event['ShadowAttribute']) && !empty($event['ShadowAttribute'])) {
|
||||
$proposalStatus = true;
|
||||
|
@ -1490,12 +1501,12 @@ class EventsController extends AppController
|
|||
}
|
||||
unset($modificationMap);
|
||||
$this->loadModel('Sighting');
|
||||
$sightingsData = $this->Sighting->eventsStatistic([$event], $this->Auth->user());
|
||||
$sightingsData = $this->Sighting->eventsStatistic([$event], $user);
|
||||
$this->set('sightingsData', $sightingsData);
|
||||
$params = $this->Event->rearrangeEventForView($event, $filters, false, $sightingsData);
|
||||
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
|
||||
$this->loadModel('Sightingdb');
|
||||
$event = $this->Sightingdb->attachToEvent($event, $this->Auth->user());
|
||||
$event = $this->Sightingdb->attachToEvent($event, $user);
|
||||
}
|
||||
$this->params->params['paging'] = array($this->modelClass => $params);
|
||||
$this->set('event', $event);
|
||||
|
@ -1504,10 +1515,10 @@ class EventsController extends AppController
|
|||
'Event.extends_uuid' => $event['Event']['uuid']
|
||||
)
|
||||
);
|
||||
$extensions = $this->Event->fetchSimpleEvents($this->Auth->user(), $extensionParams);
|
||||
$extensions = $this->Event->fetchSimpleEvents($user, $extensionParams);
|
||||
$this->set('extensions', $extensions);
|
||||
if (!empty($event['Event']['extends_uuid'])) {
|
||||
$extendedEvent = $this->Event->fetchSimpleEvents($this->Auth->user(), array('conditions' => array('Event.uuid' => $event['Event']['extends_uuid'])));
|
||||
$extendedEvent = $this->Event->fetchSimpleEvents($user, array('conditions' => array('Event.uuid' => $event['Event']['extends_uuid'])));
|
||||
if (empty($extendedEvent)) {
|
||||
$extendedEvent = $event['Event']['extends_uuid'];
|
||||
}
|
||||
|
@ -1517,8 +1528,8 @@ class EventsController extends AppController
|
|||
$this->loadModel('EventDelegation');
|
||||
$delegationConditions = array('EventDelegation.event_id' => $event['Event']['id']);
|
||||
if (!$this->_isSiteAdmin() && $this->userRole['perm_publish']) {
|
||||
$delegationConditions['OR'] = array('EventDelegation.org_id' => $this->Auth->user('org_id'),
|
||||
'EventDelegation.requester_org_id' => $this->Auth->user('org_id'));
|
||||
$delegationConditions['OR'] = array('EventDelegation.org_id' => $user['org_id'],
|
||||
'EventDelegation.requester_org_id' => $user['org_id']);
|
||||
}
|
||||
$this->set('delegationRequest', $this->EventDelegation->find('first', array(
|
||||
'conditions' => $delegationConditions,
|
||||
|
@ -1528,11 +1539,11 @@ class EventsController extends AppController
|
|||
}
|
||||
if (Configure::read('Plugin.Enrichment_services_enable')) {
|
||||
$this->loadModel('Module');
|
||||
$modules = $this->Module->getEnabledModules($this->Auth->user());
|
||||
$modules = $this->Module->getEnabledModules($user);
|
||||
if (is_array($modules)) {
|
||||
foreach ($modules as $k => $v) {
|
||||
if (isset($v['restrict'])) {
|
||||
if ($this->_isSiteAdmin() && $v['restrict'] != $this->Auth->user('org_id')) {
|
||||
if ($this->_isSiteAdmin() && $v['restrict'] != $user['org_id']) {
|
||||
unset($modules[$k]);
|
||||
}
|
||||
}
|
||||
|
@ -1542,7 +1553,7 @@ class EventsController extends AppController
|
|||
}
|
||||
if (Configure::read('Plugin.Cortex_services_enable')) {
|
||||
$this->loadModel('Module');
|
||||
$cortex_modules = $this->Module->getEnabledModules($this->Auth->user(), false, 'Cortex');
|
||||
$cortex_modules = $this->Module->getEnabledModules($user, false, 'Cortex');
|
||||
$this->set('cortex_modules', $cortex_modules);
|
||||
}
|
||||
$this->set('typeGroups', array_keys($this->Event->Attribute->typeGroupings));
|
||||
|
@ -1562,7 +1573,7 @@ class EventsController extends AppController
|
|||
'fields' => array('Orgc.id', 'Orgc.name')
|
||||
));
|
||||
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
|
||||
$this->set('sightingdbs', $this->Sightingdb->getSightingdbList($this->Auth->user()));
|
||||
$this->set('sightingdbs', $this->Sightingdb->getSightingdbList($user));
|
||||
}
|
||||
$this->set('includeSightingdb', (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')));
|
||||
$this->set('relatedEventCorrelationCount', $relatedEventCorrelationCount);
|
||||
|
@ -1663,7 +1674,19 @@ class EventsController extends AppController
|
|||
} else {
|
||||
$conditions['includeServerCorrelations'] = $this->params['named']['includeServerCorrelations'];
|
||||
}
|
||||
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
|
||||
|
||||
// Site admin can view event as different user
|
||||
if ($this->_isSiteAdmin() && isset($this->params['named']['viewAs'])) {
|
||||
$user = $this->User->getAuthUser($this->params['named']['viewAs']);
|
||||
if (empty($user)) {
|
||||
throw new NotFoundException(__("User not found"));
|
||||
}
|
||||
$this->Flash->info(__('Viewing event as %s from %s', h($user['email']), h($user['Organisation']['name'])));
|
||||
} else {
|
||||
$user = $this->Auth->user();
|
||||
}
|
||||
|
||||
$results = $this->Event->fetchEvent($user, $conditions);
|
||||
if (empty($results)) {
|
||||
throw new NotFoundException(__('Invalid event'));
|
||||
}
|
||||
|
@ -1711,7 +1734,7 @@ class EventsController extends AppController
|
|||
if ($this->_isSiteAdmin() && $event['Event']['orgc_id'] !== $this->Auth->user('org_id')) {
|
||||
$this->Flash->info(__('You are currently logged in as a site administrator and about to edit an event not belonging to your organisation. This goes against the sharing model of MISP. Use a normal user account for day to day work.'));
|
||||
}
|
||||
$this->__viewUI($event, $continue, $fromEvent);
|
||||
$this->__viewUI($user, $event, $continue, $fromEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<?php
|
||||
|
||||
App::uses('JsonExport', 'Export');
|
||||
App::uses('AppModel', 'Model');
|
||||
|
||||
|
||||
class YaraExport
|
||||
{
|
||||
private $__script_path = APP . 'files/scripts/yara/yaraexport.py';
|
||||
|
@ -13,6 +11,7 @@ class YaraExport
|
|||
private $__MAX_n_attributes = 15000;
|
||||
private $__yara_file_gen = null;
|
||||
private $__yara_file_asis = null;
|
||||
/** @var null|File */
|
||||
private $__curr_input_file = null;
|
||||
private $__scope = false;
|
||||
private $__curr_input_is_empty = true;
|
||||
|
@ -73,7 +72,13 @@ class YaraExport
|
|||
$this->separator(); // calling separator since returning '' will prevent it
|
||||
}
|
||||
$jsonData = $this->__JsonExporter->handler($data, $options);
|
||||
$this->__curr_input_file->append($jsonData);
|
||||
if ($jsonData instanceof Generator) {
|
||||
foreach ($jsonData as $part) {
|
||||
$this->__curr_input_file->append($part);
|
||||
}
|
||||
} else {
|
||||
$this->__curr_input_file->append($jsonData);
|
||||
}
|
||||
$this->__curr_input_is_empty = false;
|
||||
}
|
||||
$this->__n_attributes += $attr_count;
|
||||
|
|
|
@ -249,9 +249,16 @@ class Attribute extends AppModel
|
|||
'message' => array('Invalid ISO 8601 format')
|
||||
),
|
||||
'last_seen' => array(
|
||||
'rule' => array('datetimeOrNull'),
|
||||
'required' => false,
|
||||
'message' => array('Invalid ISO 8601 format')
|
||||
'datetimeOrNull' => array(
|
||||
'rule' => array('datetimeOrNull'),
|
||||
'required' => false,
|
||||
'message' => array('Invalid ISO 8601 format')
|
||||
),
|
||||
'validateLastSeenValue' => array(
|
||||
'rule' => array('validateLastSeenValue'),
|
||||
'required' => false,
|
||||
'message' => array('Last seen value should be greater than first seen value')
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -716,6 +723,22 @@ class Attribute extends AppModel
|
|||
return $returnValue || is_null($seen);
|
||||
}
|
||||
|
||||
public function validateLastSeenValue($fields)
|
||||
{
|
||||
$ls = $fields['last_seen'];
|
||||
if (is_null($this->data['Attribute']['first_seen']) || is_null($ls)) {
|
||||
return true;
|
||||
}
|
||||
$converted = $this->ISODatetimeToUTC(['Attribute' => [
|
||||
'first_seen' => $this->data['Attribute']['first_seen'],
|
||||
'last_seen' => $ls
|
||||
]], 'Attribute');
|
||||
if ($converted['Attribute']['first_seen'] >= $converted['Attribute']['last_seen']) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private $__hexHashLengths = array(
|
||||
'authentihash' => 64,
|
||||
'md5' => 32,
|
||||
|
|
|
@ -296,8 +296,13 @@ class AttributeTag extends AppModel
|
|||
return $allTags;
|
||||
}
|
||||
|
||||
// find all galaxies that belong to a list of attributes (contains in the same event)
|
||||
public function getAttributesClusters(array $attributes)
|
||||
/**
|
||||
* Find all galaxies that belong to a list of attributes (contains in the same event)
|
||||
* @param array $user
|
||||
* @param array $attributes
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributesClusters(array $user, array $attributes)
|
||||
{
|
||||
if (empty($attributes)) {
|
||||
return array();
|
||||
|
|
|
@ -550,7 +550,16 @@ class Feed extends AppModel
|
|||
return $sources;
|
||||
}
|
||||
|
||||
public function downloadFromFeed($actions, $feed, HttpSocket $HttpSocket = null, $user, $jobId = false)
|
||||
/**
|
||||
* @param array $actions
|
||||
* @param array $feed
|
||||
* @param HttpSocket|null $HttpSocket
|
||||
* @param array $user
|
||||
* @param int|false $jobId
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function downloadFromFeed(array $actions, array $feed, HttpSocket $HttpSocket = null, array $user, $jobId = false)
|
||||
{
|
||||
$total = count($actions['add']) + count($actions['edit']);
|
||||
$currentItem = 0;
|
||||
|
@ -561,10 +570,12 @@ class Feed extends AppModel
|
|||
foreach ($actions['add'] as $uuid) {
|
||||
try {
|
||||
$result = $this->__addEventFromFeed($HttpSocket, $feed, $uuid, $user, $filterRules);
|
||||
if ($result !== 'blocked') {
|
||||
if ($result === true) {
|
||||
$results['add']['success'] = $uuid;
|
||||
} else if ($result !== 'blocked') {
|
||||
$results['add']['fail'] = ['uuid' => $uuid, 'reason' => $result];
|
||||
$this->log("Could not add event '$uuid' from feed {$feed['Feed']['id']}: $result", LOG_WARNING);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->logException("Could not add event '$uuid' from feed {$feed['Feed']['id']}.", $e);
|
||||
$results['add']['fail'] = array('uuid' => $uuid, 'reason' => $e->getMessage());
|
||||
|
@ -579,8 +590,11 @@ class Feed extends AppModel
|
|||
$uuid = $editTarget['uuid'];
|
||||
try {
|
||||
$result = $this->__updateEventFromFeed($HttpSocket, $feed, $uuid, $editTarget['id'], $user, $filterRules);
|
||||
if ($result !== 'blocked') {
|
||||
$results['edit']['success'] = $uuid;
|
||||
if ($result === true) {
|
||||
$results['add']['success'] = $uuid;
|
||||
} else if ($result !== 'blocked') {
|
||||
$results['add']['fail'] = ['uuid' => $uuid, 'reason' => $result];
|
||||
$this->log("Could not edit event '$uuid' from feed {$feed['Feed']['id']}: $result", LOG_WARNING);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->logException("Could not edit event '$uuid' from feed {$feed['Feed']['id']}.", $e);
|
||||
|
@ -588,7 +602,7 @@ class Feed extends AppModel
|
|||
}
|
||||
|
||||
$this->__cleanupFile($feed, '/' . $uuid . '.json');
|
||||
if ($currentItem % 10 == 0) {
|
||||
if ($currentItem % 10 === 0) {
|
||||
$this->jobProgress($jobId, null, 100 * (($currentItem + 1) / $total));
|
||||
}
|
||||
$currentItem++;
|
||||
|
@ -871,7 +885,7 @@ class Feed extends AppModel
|
|||
* @param HttpSocket|null $HttpSocket
|
||||
* @param array $feed
|
||||
* @param string $uuid
|
||||
* @param $user
|
||||
* @param array $user
|
||||
* @param array|bool $filterRules
|
||||
* @return array|bool|string
|
||||
* @throws Exception
|
||||
|
@ -881,7 +895,6 @@ class Feed extends AppModel
|
|||
$event = $this->downloadAndParseEventFromFeed($feed, $uuid, $HttpSocket);
|
||||
$event = $this->__prepareEvent($event, $feed, $filterRules);
|
||||
if (is_array($event)) {
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
return $this->Event->_add($event, true, $user);
|
||||
} else {
|
||||
return $event;
|
||||
|
@ -939,13 +952,13 @@ class Feed extends AppModel
|
|||
}
|
||||
|
||||
$HttpSocket = $this->isFeedLocal($this->data) ? null : $this->__setupHttpSocket($this->data);
|
||||
if ($this->data['Feed']['source_format'] == 'misp') {
|
||||
if ($this->data['Feed']['source_format'] === 'misp') {
|
||||
$this->jobProgress($jobId, 'Fetching event manifest.');
|
||||
try {
|
||||
$actions = $this->getNewEventUuids($this->data, $HttpSocket);
|
||||
} catch (Exception $e) {
|
||||
$this->logException("Could not get new event uuids for feed $feedId.", $e);
|
||||
$this->jobProgress($jobId, 'Could not fetch event manifest. See log for more details.');
|
||||
$this->jobProgress($jobId, 'Could not fetch event manifest. See error log for more details.');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -954,7 +967,7 @@ class Feed extends AppModel
|
|||
}
|
||||
|
||||
$total = count($actions['add']) + count($actions['edit']);
|
||||
$this->jobProgress($jobId, "Fetching $total events.");
|
||||
$this->jobProgress($jobId, __("Fetching %s events.", $total));
|
||||
$result = $this->downloadFromFeed($actions, $this->data, $HttpSocket, $user, $jobId);
|
||||
$this->__cleanupFile($this->data, '/manifest.json');
|
||||
} else {
|
||||
|
|
|
@ -76,10 +76,43 @@ class MispObject extends AppModel
|
|||
'message' => array('Invalid ISO 8601 format')
|
||||
),
|
||||
'last_seen' => array(
|
||||
'rule' => array('datetimeOrNull'),
|
||||
'required' => false,
|
||||
'message' => array('Invalid ISO 8601 format')
|
||||
)
|
||||
'datetimeOrNull' => array(
|
||||
'rule' => array('datetimeOrNull'),
|
||||
'required' => false,
|
||||
'message' => array('Invalid ISO 8601 format')
|
||||
),
|
||||
'validateLastSeenValue' => array(
|
||||
'rule' => array('validateLastSeenValue'),
|
||||
'required' => false,
|
||||
'message' => array('Last seen value should be greater than first seen value')
|
||||
),
|
||||
),
|
||||
'name' => array(
|
||||
'stringNotEmpty' => array(
|
||||
'rule' => array('stringNotEmpty')
|
||||
),
|
||||
),
|
||||
'meta-category' => array(
|
||||
'stringNotEmpty' => array(
|
||||
'rule' => array('stringNotEmpty')
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'stringNotEmpty' => array(
|
||||
'rule' => array('stringNotEmpty')
|
||||
),
|
||||
),
|
||||
'template_uuid' => array(
|
||||
'uuid' => array(
|
||||
'rule' => 'uuid',
|
||||
'message' => 'Please provide a valid RFC 4122 UUID'
|
||||
),
|
||||
),
|
||||
'template_version' => array(
|
||||
'numeric' => array(
|
||||
'rule' => 'naturalNumber',
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
private $__objectDuplicationCheckCache = [];
|
||||
|
@ -184,6 +217,22 @@ class MispObject extends AppModel
|
|||
return $returnValue || is_null($seen);
|
||||
}
|
||||
|
||||
public function validateLastSeenValue($fields)
|
||||
{
|
||||
$ls = $fields['last_seen'];
|
||||
if (is_null($this->data['Object']['first_seen']) || is_null($ls)) {
|
||||
return true;
|
||||
}
|
||||
$converted = $this->Attribute->ISODatetimeToUTC(['Object' => [
|
||||
'first_seen' => $this->data['Object']['first_seen'],
|
||||
'last_seen' => $ls
|
||||
]], 'Object');
|
||||
if ($converted['Object']['first_seen'] >= $converted['Object']['last_seen']) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function afterFind($results, $primary = false)
|
||||
{
|
||||
foreach ($results as $k => $v) {
|
||||
|
|
|
@ -143,9 +143,16 @@ class ShadowAttribute extends AppModel
|
|||
'message' => array('Invalid ISO 8601 format')
|
||||
),
|
||||
'last_seen' => array(
|
||||
'rule' => array('datetimeOrNull'),
|
||||
'required' => false,
|
||||
'message' => array('Invalid ISO 8601 format')
|
||||
'datetimeOrNull' => array(
|
||||
'rule' => array('datetimeOrNull'),
|
||||
'required' => false,
|
||||
'message' => array('Invalid ISO 8601 format')
|
||||
),
|
||||
'validateLastSeenValue' => array(
|
||||
'rule' => array('validateLastSeenValue'),
|
||||
'required' => false,
|
||||
'message' => array('Last seen value should be greater than first seen value')
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -452,6 +459,22 @@ class ShadowAttribute extends AppModel
|
|||
return $this->Attribute->datetimeOrNull($fields);
|
||||
}
|
||||
|
||||
public function validateLastSeenValue($fields)
|
||||
{
|
||||
$ls = $fields['last_seen'];
|
||||
if (is_null($this->data['ShadowAttribute']['first_seen']) || is_null($ls)) {
|
||||
return true;
|
||||
}
|
||||
$converted = $this->Attribute->ISODatetimeToUTC(['ShadowAttribute' => [
|
||||
'first_seen' => $this->data['ShadowAttribute']['first_seen'],
|
||||
'last_seen' => $ls
|
||||
]], 'ShadowAttribute');
|
||||
if ($converted['ShadowAttribute']['first_seen'] >= $converted['ShadowAttribute']['last_seen']) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setDeleted($id)
|
||||
{
|
||||
$this->Behaviors->detach('SysLogLogable.SysLogLogable');
|
||||
|
|
|
@ -139,8 +139,7 @@ function syncMassEditFormAndSubmit(btn) {
|
|||
submitPopoverForm('<?php echo $id;?>', 'massEdit');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
$(function() {
|
||||
$('#AttributeDistribution').change(function() {
|
||||
if ($('#AttributeDistribution').val() == 4) $('#SGContainer').show();
|
||||
else $('#SGContainer').hide();
|
||||
|
@ -162,17 +161,18 @@ $(document).ready(function() {
|
|||
});
|
||||
|
||||
$("input, label").on('mouseleave', function(e) {
|
||||
$('#'+e.currentTarget.id).popover('destroy');
|
||||
});
|
||||
|
||||
$("input, label").on('mouseover', function(e) {
|
||||
var $e = $(e.target);
|
||||
$('#'+e.currentTarget.id).popover('destroy');
|
||||
$('#'+e.currentTarget.id).popover({
|
||||
trigger: 'focus',
|
||||
placement: 'right',
|
||||
container: 'body',
|
||||
}).popover('show');
|
||||
if (e.currentTarget.id) {
|
||||
$('#' + e.currentTarget.id).popover('destroy');
|
||||
}
|
||||
}).on('mouseover', function(e) {
|
||||
if (e.currentTarget.id) {
|
||||
$('#' + e.currentTarget.id).popover('destroy');
|
||||
$('#' + e.currentTarget.id).popover({
|
||||
trigger: 'focus',
|
||||
placement: 'right',
|
||||
container: 'body',
|
||||
}).popover('show');
|
||||
}
|
||||
});
|
||||
|
||||
// workaround for browsers like IE and Chrome that do now have an onmouseover on the 'options' of a select.
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
'disabledSubmitButton' => false, // wether to not draw the submit button
|
||||
'flag_redraw_chosen' => false, // should chosen picker be redraw at drawing time
|
||||
'redraw_debounce_time' => 200,
|
||||
'autofocus' => true,
|
||||
);
|
||||
/**
|
||||
* Supported default option in <Option> fields:
|
||||
|
@ -252,7 +253,7 @@ function submitFunction(clicked, callback) {
|
|||
$flag_addPills = false;
|
||||
?>
|
||||
<?php if ($use_select): ?>
|
||||
<select id="<?php echo $select_id; ?>" autofocus style="height: 100px; margin-bottom: 0px;" <?= $this->GenericPicker->add_select_params($defaults); ?>>
|
||||
<select id="<?php echo $select_id; ?>"<?= $defaults['autofocus'] ? ' autofocus' : '' ?> style="height: 100px; margin-bottom: 0px;" <?= $this->GenericPicker->add_select_params($defaults); ?>>
|
||||
<option></option>
|
||||
<?php
|
||||
foreach ($items as $param) {
|
||||
|
@ -301,7 +302,7 @@ function submitFunction(clicked, callback) {
|
|||
|
||||
<?php elseif (count($items) > 0): ?>
|
||||
<ul class="nav nav-pills">
|
||||
<select id="<?php echo $select_id; ?>" autofocus style="display: none;" <?php echo h($this->GenericPicker->add_select_params($defaults)); ?>></select>
|
||||
<select id="<?php echo $select_id; ?>"<?= $defaults['autofocus'] ? ' autofocus' : '' ?> style="display: none;" <?php echo h($this->GenericPicker->add_select_params($defaults)); ?>></select>
|
||||
<?php
|
||||
foreach ($items as $param) {
|
||||
echo $this->GenericPicker->add_pill($param, $defaults);
|
||||
|
|
Loading…
Reference in New Issue