mirror of https://github.com/MISP/MISP
new: [dashboard:widgets] Added support of start_date and end_date options for vairous widgets + fixed few bugs
parent
51a1441a4a
commit
1f839d91c5
|
@ -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())));;
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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', [
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue