Better error for invalid date

This commit is contained in:
James Cole
2023-08-24 05:53:17 +02:00
parent e9a8e104be
commit 5b0637558f

View File

@@ -259,14 +259,14 @@ class OperatorQuerySearch implements SearchInterface
default: default:
Log::error(sprintf('No such operator: %s', $operator)); Log::error(sprintf('No such operator: %s', $operator));
throw new FireflyException(sprintf('Unsupported search operator: "%s"', $operator)); throw new FireflyException(sprintf('Unsupported search operator: "%s"', $operator));
// some search operators are ignored, basically: // some search operators are ignored, basically:
case 'user_action': case 'user_action':
Log::info(sprintf('Ignore search operator "%s"', $operator)); Log::info(sprintf('Ignore search operator "%s"', $operator));
return false; return false;
// //
// all account related searches: // all account related searches:
// //
case 'account_is': case 'account_is':
$this->searchAccount($value, 3, 4); $this->searchAccount($value, 3, 4);
break; break;
@@ -497,9 +497,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->findNothing(); $this->collector->findNothing();
} }
break; break;
// //
// cash account // cash account
// //
case 'source_is_cash': case 'source_is_cash':
$account = $this->getCashAccount(); $account = $this->getCashAccount();
$this->collector->setSourceAccounts(new Collection([$account])); $this->collector->setSourceAccounts(new Collection([$account]));
@@ -524,9 +524,9 @@ class OperatorQuerySearch implements SearchInterface
$account = $this->getCashAccount(); $account = $this->getCashAccount();
$this->collector->excludeAccounts(new Collection([$account])); $this->collector->excludeAccounts(new Collection([$account]));
break; break;
// //
// description // description
// //
case 'description_starts': case 'description_starts':
$this->collector->descriptionStarts([$value]); $this->collector->descriptionStarts([$value]);
break; break;
@@ -553,9 +553,9 @@ class OperatorQuerySearch implements SearchInterface
case '-description_is': case '-description_is':
$this->collector->descriptionIsNot($value); $this->collector->descriptionIsNot($value);
break; break;
// //
// currency // currency
// //
case 'currency_is': case 'currency_is':
$currency = $this->findCurrency($value); $currency = $this->findCurrency($value);
if (null !== $currency) { if (null !== $currency) {
@@ -592,9 +592,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->findNothing(); $this->collector->findNothing();
} }
break; break;
// //
// attachments // attachments
// //
case 'has_attachments': case 'has_attachments':
case '-has_no_attachments': case '-has_no_attachments':
Log::debug('Set collector to filter on attachments.'); Log::debug('Set collector to filter on attachments.');
@@ -605,8 +605,8 @@ class OperatorQuerySearch implements SearchInterface
Log::debug('Set collector to filter on NO attachments.'); Log::debug('Set collector to filter on NO attachments.');
$this->collector->hasNoAttachments(); $this->collector->hasNoAttachments();
break; break;
// //
// categories // categories
case '-has_any_category': case '-has_any_category':
case 'has_no_category': case 'has_no_category':
$this->collector->withoutCategory(); $this->collector->withoutCategory();
@@ -684,9 +684,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->findNothing(); $this->collector->findNothing();
} }
break; break;
// //
// budgets // budgets
// //
case '-has_any_budget': case '-has_any_budget':
case 'has_no_budget': case 'has_no_budget':
$this->collector->withoutBudget(); $this->collector->withoutBudget();
@@ -765,9 +765,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->findNothing(); $this->collector->findNothing();
} }
break; break;
// //
// bill // bill
// //
case '-has_any_bill': case '-has_any_bill':
case 'has_no_bill': case 'has_no_bill':
$this->collector->withoutBill(); $this->collector->withoutBill();
@@ -844,9 +844,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->findNothing(); $this->collector->findNothing();
} }
break; break;
// //
// tags // tags
// //
case '-has_any_tag': case '-has_any_tag':
case 'has_no_tag': case 'has_no_tag':
$this->collector->withoutTags(); $this->collector->withoutTags();
@@ -874,9 +874,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->setWithoutSpecificTags($result); $this->collector->setWithoutSpecificTags($result);
} }
break; break;
// //
// notes // notes
// //
case 'notes_contains': case 'notes_contains':
$this->collector->notesContain($value); $this->collector->notesContain($value);
break; break;
@@ -915,9 +915,9 @@ class OperatorQuerySearch implements SearchInterface
case '-reconciled': case '-reconciled':
$this->collector->isNotReconciled(); $this->collector->isNotReconciled();
break; break;
// //
// amount // amount
// //
case 'amount_is': case 'amount_is':
// strip comma's, make dots. // strip comma's, make dots.
Log::debug(sprintf('Original value "%s"', $value)); Log::debug(sprintf('Original value "%s"', $value));
@@ -988,9 +988,9 @@ class OperatorQuerySearch implements SearchInterface
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountMore($amount); $this->collector->foreignAmountMore($amount);
break; break;
// //
// transaction type // transaction type
// //
case 'transaction_type': case 'transaction_type':
$this->collector->setTypes([ucfirst($value)]); $this->collector->setTypes([ucfirst($value)]);
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
@@ -999,161 +999,161 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->excludeTypes([ucfirst($value)]); $this->collector->excludeTypes([ucfirst($value)]);
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
break; break;
// //
// dates // dates
// //
case '-date_on': case '-date_on':
case 'date_on': case 'date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactDateParams($range, $prohibited); $this->setExactDateParams($range, $prohibited);
return false; return false;
case 'date_before': case 'date_before':
case '-date_after': case '-date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setDateBeforeParams($range); $this->setDateBeforeParams($range);
return false; return false;
case 'date_after': case 'date_after':
case '-date_before': case '-date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setDateAfterParams($range); $this->setDateAfterParams($range);
return false; return false;
case 'interest_date_on': case 'interest_date_on':
case '-interest_date_on': case '-interest_date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('interest_date', $range, $prohibited); $this->setExactMetaDateParams('interest_date', $range, $prohibited);
return false; return false;
case 'interest_date_before': case 'interest_date_before':
case '-interest_date_after': case '-interest_date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('interest_date', $range); $this->setMetaDateBeforeParams('interest_date', $range);
return false; return false;
case 'interest_date_after': case 'interest_date_after':
case '-interest_date_before': case '-interest_date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('interest_date', $range); $this->setMetaDateAfterParams('interest_date', $range);
return false; return false;
case 'book_date_on': case 'book_date_on':
case '-book_date_on': case '-book_date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('book_date', $range, $prohibited); $this->setExactMetaDateParams('book_date', $range, $prohibited);
return false; return false;
case 'book_date_before': case 'book_date_before':
case '-book_date_after': case '-book_date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('book_date', $range); $this->setMetaDateBeforeParams('book_date', $range);
return false; return false;
case 'book_date_after': case 'book_date_after':
case '-book_date_before': case '-book_date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('book_date', $range); $this->setMetaDateAfterParams('book_date', $range);
return false; return false;
case 'process_date_on': case 'process_date_on':
case '-process_date_on': case '-process_date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('process_date', $range, $prohibited); $this->setExactMetaDateParams('process_date', $range, $prohibited);
return false; return false;
case 'process_date_before': case 'process_date_before':
case '-process_date_after': case '-process_date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('process_date', $range); $this->setMetaDateBeforeParams('process_date', $range);
return false; return false;
case 'process_date_after': case 'process_date_after':
case '-process_date_before': case '-process_date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('process_date', $range); $this->setMetaDateAfterParams('process_date', $range);
return false; return false;
case 'due_date_on': case 'due_date_on':
case '-due_date_on': case '-due_date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('due_date', $range, $prohibited); $this->setExactMetaDateParams('due_date', $range, $prohibited);
return false; return false;
case 'due_date_before': case 'due_date_before':
case '-due_date_after': case '-due_date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('due_date', $range); $this->setMetaDateBeforeParams('due_date', $range);
return false; return false;
case 'due_date_after': case 'due_date_after':
case '-due_date_before': case '-due_date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('due_date', $range); $this->setMetaDateAfterParams('due_date', $range);
return false; return false;
case 'payment_date_on': case 'payment_date_on':
case '-payment_date_on': case '-payment_date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('payment_date', $range, $prohibited); $this->setExactMetaDateParams('payment_date', $range, $prohibited);
return false; return false;
case 'payment_date_before': case 'payment_date_before':
case '-payment_date_after': case '-payment_date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('payment_date', $range); $this->setMetaDateBeforeParams('payment_date', $range);
return false; return false;
case 'payment_date_after': case 'payment_date_after':
case '-payment_date_before': case '-payment_date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('payment_date', $range); $this->setMetaDateAfterParams('payment_date', $range);
return false; return false;
case 'invoice_date_on': case 'invoice_date_on':
case '-invoice_date_on': case '-invoice_date_on':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('invoice_date', $range, $prohibited); $this->setExactMetaDateParams('invoice_date', $range, $prohibited);
return false; return false;
case 'invoice_date_before': case 'invoice_date_before':
case '-invoice_date_after': case '-invoice_date_after':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('invoice_date', $range); $this->setMetaDateBeforeParams('invoice_date', $range);
return false; return false;
case 'invoice_date_after': case 'invoice_date_after':
case '-invoice_date_before': case '-invoice_date_before':
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('invoice_date', $range); $this->setMetaDateAfterParams('invoice_date', $range);
return false; return false;
case 'created_at_on': case 'created_at_on':
case '-created_at_on': case '-created_at_on':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactObjectDateParams('created_at', $range, $prohibited); $this->setExactObjectDateParams('created_at', $range, $prohibited);
return false; return false;
case 'created_at_before': case 'created_at_before':
case '-created_at_after': case '-created_at_after':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setObjectDateBeforeParams('created_at', $range); $this->setObjectDateBeforeParams('created_at', $range);
return false; return false;
case 'created_at_after': case 'created_at_after':
case '-created_at_before': case '-created_at_before':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setObjectDateAfterParams('created_at', $range); $this->setObjectDateAfterParams('created_at', $range);
return false; return false;
case 'updated_at_on': case 'updated_at_on':
case '-updated_at_on': case '-updated_at_on':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setExactObjectDateParams('updated_at', $range, $prohibited); $this->setExactObjectDateParams('updated_at', $range, $prohibited);
return false; return false;
case 'updated_at_before': case 'updated_at_before':
case '-updated_at_after': case '-updated_at_after':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setObjectDateBeforeParams('updated_at', $range); $this->setObjectDateBeforeParams('updated_at', $range);
return false; return false;
case 'updated_at_after': case 'updated_at_after':
case '-updated_at_before': case '-updated_at_before':
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($value); $range = $this->parseDateRange($operator, $value);
$this->setObjectDateAfterParams('updated_at', $range); $this->setObjectDateAfterParams('updated_at', $range);
return false; return false;
// //
// external URL // external URL
// //
case '-any_external_url': case '-any_external_url':
case 'no_external_url': case 'no_external_url':
$this->collector->withoutExternalUrl(); $this->collector->withoutExternalUrl();
@@ -1196,9 +1196,9 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->externalUrlDoesNotEnd($value); $this->collector->externalUrlDoesNotEnd($value);
break; break;
// //
// other fields // other fields
// //
case 'external_id_is': case 'external_id_is':
$this->collector->setExternalId($value); $this->collector->setExternalId($value);
break; break;
@@ -1550,13 +1550,22 @@ class OperatorQuerySearch implements SearchInterface
* @return array * @return array
* @throws FireflyException * @throws FireflyException
*/ */
private function parseDateRange(string $value): array private function parseDateRange(string $type, string $value): array
{ {
$parser = new ParseDateString(); $parser = new ParseDateString();
if ($parser->isDateRange($value)) { if ($parser->isDateRange($value)) {
return $parser->parseRange($value); return $parser->parseRange($value);
} }
$parsedDate = $parser->parseDate($value); try {
$parsedDate = $parser->parseDate($value);
} catch (FireflyException $e) {
Log::debug(sprintf('Could not parse date "%s", will return empty array.', $value));
$this->invalidOperators[] = [
'type' => $type,
'value' => (string)$value,
];
return [];
}
return [ return [
'exact' => $parsedDate, 'exact' => $parsedDate,