new: [dashboard:widgets] Added support of start_date and end_date options for vairous widgets + fixed few bugs

pull/9247/head
Sami Mokaddem 2023-08-09 14:37:31 +02:00
parent 51a1441a4a
commit 1f839d91c5
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
8 changed files with 188 additions and 17 deletions

View File

@ -13,6 +13,8 @@ class APIActivityWidget
'month' => 'Who contributed most this month? (boolean)',
'previous_month' => 'Who contributed most the previous, finished month? (boolean)',
'year' => 'Which contributed most this year? (boolean)',
'start_date' => 'The ISO 8601 date format at which to start',
'end_date' => 'The ISO 8601 date format at which to end. (Leave empty for today)',
];
public $description = 'Basic widget showing some server statistics in regards to MISP.';
public $cacheLifetime = 10;
@ -32,6 +34,14 @@ class APIActivityWidget
$end = new DateTime(date('Y-m-d', strtotime('last day of last month 23:59:59', time())));
} else if (!empty($options['year'])) {
$begin = new DateTime(date('Y-m-d', strtotime('first day of this year 00:00:00', time())));
} else if (!empty($options['start_date'])) {
$begin = new DateTime($options['start_date']);
$end = [];
if (empty($options['end_date'])) {
$end = new DateTime();
} else {
$end = new DateTime($options['end_date']);
}
} else {
$begin = new DateTime(date('Y-m-d', strtotime('-7 days', time())));;
}

View File

@ -32,6 +32,14 @@ class LoginsWidget
$end = date('Y-m-d H:i:s', strtotime('last day of last month 23:59:59', time()));
} else if (!empty($options['year'])) {
$begin = date('Y-m-d', strtotime('first day of this year 00:00:00', time()));
} else if (!empty($options['start_date'])) {
$begin = date($options['start_date']);
$end = [];
if (empty($options['end_date'])) {
$end = date(time());
} else {
$end = date($options['end_date']);
}
} else {
$begin = date('Y-m-d H:i:s', strtotime('-7 days', time()));
}

View File

@ -18,6 +18,8 @@ class NewOrgsWidget
'previous_month' => 'Who contributed most the previous, finished month? (boolean)',
'first_half_year' => 'Who contributed most the first half-year (between Jan and June)? (boolean)',
'second_half_year' => 'Who contributed most the second half-year (between July and Dec)? (boolean)',
'start_date' => 'The ISO 8601 date format at which to start',
'end_date' => 'The ISO 8601 date format at which to end. (Leave empty for today)',
'year' => 'Which organisations have been added this year? (boolean)',
'local' => 'Should the list only show local organisations? (boolean or list of booleans, defaults to 1. To get both sets, use [0,1])',
'fields' => 'Which fields should be displayed, by default all are selected. Pass a list with the following options: [id, uuid, name, sector, type, nationality, creation_date]'
@ -69,6 +71,15 @@ class NewOrgsWidget
$condition = strtotime('first day of july this year 00:00:00', time());
$end_condition = strtotime('last day of december this year 23:59:59', time());
$this->tableDescription = __('The %d newest organisations created during the current half year', $limit);
} else if (!empty($options['start_date'])) {
$condition = strtotime($options['start_date'], time());
$end_condition = [];
if (empty($options['end_date'])) {
$end_condition = time();
} else {
$end_condition = strtotime($options['end_date'], time());
}
$this->tableDescription = __('The %d newest organisations created since %s', $limit, $options['start_date']);
} else {
$this->tableDescription = __('The %d newest organisations created', $limit);
return null;

View File

@ -17,6 +17,8 @@ class NewUsersWidget
'month' => 'Which organisations have been added this month? (boolean)',
'previous_month' => 'Who contributed most the previous, finished month? (boolean)',
'year' => 'Which organisations have been added this year? (boolean)',
'start_date' => 'The ISO 8601 date format at which to start',
'end_date' => 'The ISO 8601 date format at which to end. (Leave empty for today)',
'fields' => 'Which fields should be displayed, by default all are selected. Pass a list with the following options: [id, email, Organisation.name, Role.name, date_created]'
];
private $validFilterKeys = [
@ -65,6 +67,15 @@ class NewUsersWidget
} else if (!empty($options['year'])) {
$condition = strtotime('first day of this year 00:00:00', time());
$this->tableDescription = __('The %d newest users created during the current year', $limit);
} else if (!empty($options['start_date'])) {
$condition = strtotime($options['start_date'], time());
$end_condition = [];
if (empty($options['end_date'])) {
$end_condition = time();
} else {
$end_condition = strtotime($options['end_date'], time());
}
$this->tableDescription = __('The %d newest organisations created since %s', $limit, $options['start_date']);
} else {
$this->tableDescription = __('The %d newest users created', $limit);
return null;

View File

@ -13,6 +13,8 @@ class OrgContributionToplistWidget
'year' => 'Which contributed most this year? (boolean)',
'first_half_year' => 'Which contributed most the first half-year (between Jan and June)? (boolean)',
'second_half_year' => 'Which contributed most the second half-year (between July and Dec)? (boolean)',
'start_date' => 'The ISO 8601 date format at which to start',
'end_date' => 'The ISO 8601 date format at which to end. (Leave empty for today)',
'filter' => 'A list of filters by organisation meta information (nationality, sector, type, name, uuid, local (- expects a boolean or a list of boolean values)) to include. (dictionary, prepending values with ! uses them as a negation)',
'limit' => 'Limits the number of displayed tags. Default: 10'
];
@ -54,6 +56,14 @@ class OrgContributionToplistWidget
} else if (!empty($options['current_half'])) {
$condition = strtotime('first day of july this year 00:00:00', time());
$end_condition = strtotime('last day of december this year 23:59:59', time());
} else if (!empty($options['start_date'])) {
$condition = strtotime($options['start_date'], time());
$end_condition = [];
if (empty($options['end_date'])) {
$end_condition = time();
} else {
$end_condition = strtotime($options['end_date'], time());
}
} else {
return null;
}
@ -61,12 +71,12 @@ class OrgContributionToplistWidget
if (!empty($condition)) {
$datetime = new DateTime();
$datetime->setTimestamp($condition);
$conditions['Event.timestamp >='] = $datetime->format('Y-m-d H:i:s');
$conditions['Event.timestamp >='] = $datetime->getTimestamp();
}
if (!empty($end_condition)) {
$datetime = new DateTime();
$datetime->setTimestamp($end_condition);
$conditions['Event.timestamp <='] = $datetime->format('Y-m-d H:i:s');
$conditions['Event.timestamp <='] = $datetime->getTimestamp();
}
return $conditions;
}
@ -75,10 +85,6 @@ class OrgContributionToplistWidget
public function handler($user, $options = array())
{
$params = ['conditions' => []];
$timeConditions = $this->timeConditions($options);
if ($timeConditions) {
$params['conditions']['AND'][] = $timeConditions;
}
if (!empty($options['filter']) && is_array($options['filter'])) {
foreach ($this->validFilterKeys as $filterKey) {
if (!empty($options['filter'][$filterKey])) {
@ -108,7 +114,12 @@ class OrgContributionToplistWidget
'fields' => ['Organisation.id', 'Organisation.name'],
'conditions' => $params['conditions']
]);
$conditions = ['Event.orgc_id IN' => array_keys($org_ids)];
$conditions = [];
$conditions['AND'][] = ['Event.orgc_id IN' => array_keys($org_ids)];
$timeConditions = $this->timeConditions($options);
if ($timeConditions) {
$conditions['AND'][]['AND'] = $timeConditions;
}
$this->Event = ClassRegistry::init('Event');
$this->Event->virtualFields['frequency'] = 0;
$orgs = $this->Event->find('all', [

View File

@ -8,7 +8,9 @@ class OrganisationMapWidget
public $height = 4;
public $params = [
'filter' => 'A list of filters by organisation meta information (sector, type, local (- expects a boolean or a list of boolean values)) to include. (dictionary, prepending values with ! uses them as a negation)',
'limit' => 'Limits the number of displayed tags. Default: 10'
'start_date' => 'The ISO 8601 date format at which to start',
'end_date' => 'The ISO 8601 date format at which to end. (Leave empty for today)',
'limit' => 'Limits the number of displayed tags. Default: 10',
];
public $cacheLifetime = null;
public $autoRefreshDelay = false;
@ -58,6 +60,12 @@ class OrganisationMapWidget
}
}
}
if ($options['start_date']) {
$params['conditions']['AND']['Organisation.date_created >='] = (new DateTime($options['start_date']))->format('Y-m-d H:i:s');
if (empty($options['end_date'])) {
$params['conditions']['AND']['Organisation.date_created <='] = (new DateTime($options['end_date']))->format('Y-m-d H:i:s');
}
}
$this->Organisation = ClassRegistry::init('Organisation');
$orgs = $this->Organisation->find('all', [
'recursive' => -1,

View File

@ -10,6 +10,8 @@ class UsageDataWidget
public $autoRefreshDelay = false;
public $params = [
'filter' => 'A list of filters by organisation meta information (nationality, sector, type, name, uuid) to include. (dictionary, prepending values with ! uses them as a negation)',
'start_date' => 'The ISO 8601 date format for which to show changes',
'end_date' => 'The ISO 8601 date format for which to show changes. (Leave empty for today)',
];
private $User = null;
private $Event = null;
@ -52,6 +54,7 @@ class UsageDataWidget
$this->Thread = ClassRegistry::init('Thread');
$this->Correlation = ClassRegistry::init('Correlation');
$thisMonth = strtotime('first day of this month');
$hasDateRange = !empty($options['start_date']);
$orgConditions = [];
$orgIdList = null;
if (!empty($options['filter']) && is_array($options['filter'])) {
@ -98,12 +101,12 @@ class UsageDataWidget
'Events' => [
'title' => 'Events',
'value' => $eventsCount,
'change' => $this->getEventsCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getEventsCountDateRange($orgConditions, $orgIdList, $options) : $this->getEventsCountMonth($orgConditions, $orgIdList, $thisMonth)
],
'Attributes' => [
'title' => 'Attributes',
'value' => $attributesCount,
'change' => $this->getAttributesCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getAttributesCountDateRange($orgConditions, $orgIdList, $options) : $this->getAttributesCountMonth($orgConditions, $orgIdList, $thisMonth)
],
'Attributes / event' => [
'title' => 'Attributes / event',
@ -120,7 +123,7 @@ class UsageDataWidget
'Users' => [
'title' => 'Users',
'value' => $usersCount,
'change' => $this->getUsersCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getUsersCountDateRange($orgConditions, $orgIdList, $options) : $this->getUsersCountMonth($orgConditions, $orgIdList, $thisMonth)
],
'Users with PGP keys' => [
'title' => 'Users with PGP keys',
@ -133,12 +136,12 @@ class UsageDataWidget
'Organisations' => [
'title' => 'Organisations',
'value' => $this->getOrgsCount($orgConditions, $orgIdList, $thisMonth),
'change' => $this->getOrgsCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getOrgsCountDateRange($orgConditions, $orgIdList, $options) : $this->getOrgsCountMonth($orgConditions, $orgIdList, $thisMonth)
],
'Local organisations' => [
'title' => 'Local organisations',
'value' => $localOrgsCount,
'change' => $this->getLocalOrgsCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getLocalOrgsCountDateRange($orgConditions, $orgIdList, $options) : $this->getLocalOrgsCountMonth($orgConditions, $orgIdList, $thisMonth)
],
'Event creator orgs' => [
'title' => 'Event creator orgs', 'value' => $this->getContributingOrgsCount($orgConditions, $orgIdList, $thisMonth)
@ -149,12 +152,12 @@ class UsageDataWidget
'Discussion threads' => [
'title' => 'Discussions threads',
'value' => $this->getThreadsCount($orgConditions, $orgIdList, $thisMonth),
'change' => $this->getThreadsCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getThreadsCountDateRange($orgConditions, $orgIdList, $options) : $this->getThreadsCountMonth($orgConditions, $orgIdList, $thisMonth)
],
'Discussion posts' => [
'title' => 'Discussion posts',
'value' => $this->getPostsCount($orgConditions, $orgIdList, $thisMonth),
'change' => $this->getPostsCountMonth($orgConditions, $orgIdList, $thisMonth)
'change' => $hasDateRange ? $this->getPostsCountDateRange($orgConditions, $orgIdList, $options) : $this->getPostsCountMonth($orgConditions, $orgIdList, $thisMonth)
]
];
if(!empty(Configure::read('Security.advanced_authkeys'))){
@ -165,6 +168,20 @@ class UsageDataWidget
return $statistics;
}
private function prepareDateRangeConditions(array $options, $datefield, $convertToTimestamp = false): array
{
$timeConditions = [];
if (!empty($options['start_date'])) {
$sd = new DateTime($options['start_date']);
$timeConditions[sprintf('%s >=', $datefield)] = $convertToTimestamp? $sd->getTimestamp() : $sd->format('Y-m-d H:i:s');
if (!empty($options['end_date'])) {
$ed = new DateTime($options['end_date']);
$timeConditions[sprintf('%s <=', $datefield)] = $convertToTimestamp? $ed->getTimestamp() : $ed->format('Y-m-d H:i:s');
}
}
return $timeConditions;
}
private function getEventsCount($orgConditions, $orgIdList, $thisMonth)
{
$conditions = [];
@ -202,6 +219,18 @@ class UsageDataWidget
]);
}
private function getEventsCountDateRange($orgConditions, $orgIdList, $options)
{
$conditions = $this->prepareDateRangeConditions($options, 'Event.timestamp', true);
if (!empty($orgIdList)) {
$conditions['AND'][] = ['Event.orgc_id IN' => $orgIdList];
}
return $this->Event->find('count', [
'conditions' => $conditions,
'recursive' => -1
]);
}
private function getAttributesCount($orgConditions, $orgIdList, $thisMonth)
{
$conditions = ['Attribute.deleted' => 0];
@ -234,6 +263,20 @@ class UsageDataWidget
]);
}
private function getAttributesCountDateRange($orgConditions, $orgIdList, $options)
{
$conditions = $this->prepareDateRangeConditions($options, 'Attribute.timestamp', true);
$conditions['Attribute.deleted'] = 0;
if (!empty($orgIdList)) {
$conditions['AND'][] = ['Event.orgc_id IN' => $orgIdList];
}
return $this->Event->Attribute->find('count', [
'conditions' => $conditions,
'contain' => 'Event.orgc_id',
'recursive' => -1
]);
}
private function getOrgsCount($orgConditions, $orgIdList, $thisMonth)
{
return $this->User->Organisation->find('count', [
@ -256,6 +299,16 @@ class UsageDataWidget
]);
}
private function getOrgsCountDateRange($orgConditions, $orgIdList, $options)
{
return $this->User->Organisation->find('count', [
'conditions' => [
'AND' => $orgConditions,
$this->prepareDateRangeConditions($options, 'Organisation.date_created'),
]
]);
}
private function getLocalOrgsCount($orgConditions, $orgIdList, $thisMonth)
{
return $this->User->Organisation->find('count', [
@ -280,6 +333,17 @@ class UsageDataWidget
]);
}
private function getLocalOrgsCountDateRange($orgConditions, $orgIdList, $options)
{
return $this->User->Organisation->find('count', [
'conditions' => [
'Organisation.local' => 1,
'AND' => $orgConditions,
$this->prepareDateRangeConditions($options, 'Organisation.date_created'),
]
]);
}
private function getProposalsCount($orgConditions, $orgIdList, $thisMonth)
{
$conditions = ['deleted' => 0];
@ -316,6 +380,18 @@ class UsageDataWidget
]);
}
private function getUsersCountDateRange($orgConditions, $orgIdList, $options)
{
$conditions = $this->prepareDateRangeConditions($options, 'User.date_created', true);
if (!empty($orgIdList)) {
$conditions['User.org_id IN'] = $orgIdList;
}
return $this->User->find('count', [
'recursive' => -1,
'conditions' => $conditions
]);
}
private function getUsersCountPgp($orgConditions, $orgIdList, $thisMonth)
{
$conditions = ['User.gpgkey !=' => ''];
@ -368,6 +444,19 @@ class UsageDataWidget
]);
}
private function getThreadsCountDateRange($orgConditions, $orgIdList, $options)
{
$conditions = $this->prepareDateRangeConditions($options, 'Thread.date_created');
$conditions['Thread.post_count >'] = 0;
if ($orgConditions) {
$conditions['AND'][] = ['Thread.org_id IN' => (!empty($orgIdList) ? $orgIdList : [-1])];
}
return $this->Thread->find('count', [
'conditions' => $conditions,
'recursive' => -1
]);
}
private function getPostsCount($orgConditions, $orgIdList, $thisMonth)
{
$conditions = [];
@ -396,6 +485,19 @@ class UsageDataWidget
]);
}
private function getPostsCountDateRange($orgConditions, $orgIdList, $options)
{
$conditions = $this->prepareDateRangeConditions($options, 'Post.date_created');
if ($orgConditions) {
$conditions['AND'][] = ['User.org_id IN' => (!empty($orgIdList) ? $orgIdList : [-1])];
}
return $this->Thread->Post->find('count', [
'conditions' => $conditions,
'contain' => ['User.org_id'],
'recursive' => -1
]);
}
/* There is nothing sensitive in here.
public function checkPermissions($user)

View File

@ -11,6 +11,8 @@ class UserContributionToplistWidget
'month' => 'Who contributed most this month? (boolean)',
'previous_month' => 'Who contributed most the previous, finished month? (boolean)',
'year' => 'Which contributed most this year? (boolean)',
'start_date' => 'The ISO 8601 date format at which to start',
'end_date' => 'The ISO 8601 date format at which to end. (Leave empty for today)',
'filter' => 'A list of filters by organisation meta information (nationality, sector, type, name, uuid, local (- expects a boolean or a list of boolean values)) to include. (dictionary, prepending values with ! uses them as a negation)',
'limit' => 'Limits the number of displayed tags. Default: 10'
];
@ -47,6 +49,14 @@ class UserContributionToplistWidget
$end_condition = strtotime('last day of last month 23:59:59', time());
} else if (!empty($options['year'])) {
$condition = strtotime('first day of this year 00:00:00', time());
} else if (!empty($options['start_date'])) {
$condition = strtotime($options['start_date'], time());
$end_condition = [];
if (empty($options['end_date'])) {
$end_condition = time();
} else {
$end_condition = strtotime($options['end_date'], time());
}
} else {
return null;
}
@ -54,12 +64,12 @@ class UserContributionToplistWidget
if (!empty($condition)) {
$datetime = new DateTime();
$datetime->setTimestamp($condition);
$conditions['Event.timestamp >='] = $datetime->format('Y-m-d H:i:s');
$conditions['Event.timestamp >='] = $datetime->getTimestamp();
}
if (!empty($end_condition)) {
$datetime = new DateTime();
$datetime->setTimestamp($end_condition);
$conditions['Event.timestamp <='] = $datetime->format('Y-m-d H:i:s');
$conditions['Event.timestamp <='] = $datetime->getTimestamp();
}
return $conditions;
}