Cutelyst  3.5.0
validatorafter.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2022 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatorafter_p.h"
7 
8 #include <QLocale>
9 #include <QTimeZone>
10 
11 using namespace Cutelyst;
12 
13 ValidatorAfter::ValidatorAfter(const QString &field, const QVariant &comparison, const QString &timeZone, const char *inputFormat, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
14  ValidatorRule(*new ValidatorAfterPrivate(field, comparison, timeZone, inputFormat, messages, defValKey))
15 {
16 }
17 
19 {
20 
21 }
22 
24 {
25  ValidatorReturnType result;
26 
27  Q_D(const ValidatorAfter);
28 
29  const QString v = value(params);
30 
31  if (!v.isEmpty()) {
32 
33  const QTimeZone tz = d->extractTimeZone(c, params, d->timeZone);
34 
35  const QVariant _comp = (d->comparison.userType() == QMetaType::QString)
36  ? d->extractOtherDateTime(c, params, d->comparison.toString(), tz, d->inputFormat)
37  : d->comparison;
38 
39  if (_comp.userType() == QMetaType::QDate) {
40 
41  const QDate odate = _comp.toDate();
42  if (Q_UNLIKELY(!odate.isValid())) {
43  qCWarning(C_VALIDATOR, "ValidatorAfter: Invalid comparison date and time for field %s at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
45  } else {
46  const QDate date = d->extractDate(c, v, d->inputFormat);
47  if (Q_UNLIKELY(!date.isValid())) {
48  qCWarning(C_VALIDATOR, "ValidatorAfter: Can not parse input date \"%s\" for field %s at %s::%s.", qPrintable(v), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
49  result.errorMessage = parsingError(c, odate);
50  } else {
51  if (Q_UNLIKELY(date <= odate)) {
52  qCDebug(C_VALIDATOR, "ValidatorAfter: Validation failed at %s::%s for field %s: Input date \"%s\" is not after \"%s\".", qPrintable(c->controllerName()), qPrintable(c->actionName()), qPrintable(field()), qPrintable(date.toString()), qPrintable(odate.toString()));
53  result.errorMessage = validationError(c, odate);
54  } else {
55  result.value.setValue(date);
56  }
57  }
58  }
59 
60  } else if (_comp.userType() == QMetaType::QDateTime) {
61 
62  const QDateTime odatetime = _comp.toDateTime();
63  if (Q_UNLIKELY(!odatetime.isValid())) {
64  qCWarning(C_VALIDATOR, "ValidatorAfter: Invalid comparison date and time for field %s at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
66  } else {
67  const QDateTime datetime = d->extractDateTime(c, v, d->inputFormat, tz);
68  if (Q_UNLIKELY(!datetime.isValid())) {
69  qCWarning(C_VALIDATOR, "ValidatorAfter: Can not parse input date and time \"%s\" for field %s at %s::%s.", qPrintable(v), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
70  result.errorMessage = parsingError(c, odatetime);
71  } else {
72  if (Q_UNLIKELY(datetime <= odatetime)) {
73  qCDebug(C_VALIDATOR, "ValidatorAfter: Validation failed at %s::%s for field %s: Input date and time \"%s\" is not after \"%s\".", qPrintable(c->controllerName()), qPrintable(c->actionName()), qPrintable(field()), qPrintable(datetime.toString()), qPrintable(odatetime.toString()));
74  result.errorMessage = validationError(c, odatetime);
75  } else {
76  result.value.setValue(datetime);
77  }
78  }
79  }
80 
81  } else if (_comp.userType() == QMetaType::QTime) {
82 
83  const QTime otime = _comp.toTime();
84  if (Q_UNLIKELY(!otime.isValid())) {
85  qCWarning(C_VALIDATOR, "ValidatorAfter: Invalid comparison time for field %s at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
87  } else {
88  const QTime time = d->extractTime(c, v, d->inputFormat);
89  if (Q_UNLIKELY(!time.isValid())) {
90  qCWarning(C_VALIDATOR, "ValidatorAfter: Can not parse input time \"%s\" for field %s at %s::%s.", qPrintable(v), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
91  result.errorMessage = parsingError(c, otime);
92  } else {
93  if (Q_UNLIKELY(time <= otime)) {
94  qCDebug(C_VALIDATOR, "ValidatorAfter: Validation failed at %s::%s for field %s: Input time \"%s\" is not after \"%s\".", qPrintable(c->controllerName()), qPrintable(c->actionName()), qPrintable(field()), qPrintable(time.toString()), qPrintable(otime.toString()));
95  result.errorMessage = validationError(c, otime);
96  } else {
97  result.value.setValue(time);
98  }
99  }
100  }
101 
102  } else {
103  qCWarning(C_VALIDATOR) << "ValidatorAfter: Invalid validation data for field" << field() << "at" << c->controllerName() << "::" << c->actionName() << ":" << d->comparison;
104  result.errorMessage = validationDataError(c);
105  }
106  } else {
107  defaultValue(c, &result, "ValidatorAfter");
108  }
109 
110  return result;
111 }
112 
114 {
115  QString error;
116 
117  const QString _label = label(c);
118  if (_label.isEmpty()) {
119 
120  switch (errorData.userType()) {
121  case QMetaType::QDate:
122  error = QStringLiteral("Has to be after %1.").arg(errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
123  break;
124  case QMetaType::QDateTime:
125  error = QStringLiteral("Has to be after %1.").arg(errorData.toDateTime().toString(c->locale().dateTimeFormat(QLocale::ShortFormat)));
126  break;
127  case QMetaType::QTime:
128  error = QStringLiteral("Has to be after %1.").arg(errorData.toTime().toString(c->locale().timeFormat(QLocale::ShortFormat)));
129  break;
130  default:
131  error = validationDataError(c);
132  break;
133  }
134 
135  } else {
136 
137  switch(errorData.userType()) {
138  case QMetaType::QDate:
139  error = c->translate("Cutelyst::ValidatorAfter", "The date in the “%1” field must be after %2.").arg(_label, errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
140  break;
141  case QMetaType::QDateTime:
142  error = c->translate("Cutelyst::ValidatorAfter", "The date and time in the “%1” field must be after %2.").arg(_label, errorData.toDateTime().toString(c->locale().dateTimeFormat(QLocale::ShortFormat)));
143  break;
144  case QMetaType::QTime:
145  error = c->translate("Cutelyst::ValidatorAfter", "The time in the “%1” field must be after %2.").arg(_label, errorData.toTime().toString(c->locale().timeFormat(QLocale::ShortFormat)));
146  break;
147  default:
148  error = validationDataError(c);
149  break;
150  }
151 
152  }
153 
154  return error;
155 }
156 
158 {
159  QString error;
160 
161  Q_UNUSED(errorData)
162  error = c->translate("Cutelyst::ValidatorAfter", "The comparison value is not a valid date and/or time, or cannot be found.");
163 
164  return error;
165 }
166 
168 {
169  QString error;
170 
171  Q_D(const ValidatorAfter);
172 
173  const QString _label = label(c);
174  if (d->inputFormat) {
175  if (_label.isEmpty()) {
176  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed according to the follwing date and/or time format: %1").arg(c->translate(d->translationContext.data(), d->inputFormat));
177  } else {
178  error = c->translate("Cutelyst::ValidatorAfter", "The value of the “%1” field could not be parsed according to the follwing date and/or time format: %2").arg(_label, c->translate(d->translationContext.data(), d->inputFormat));
179  }
180  } else {
181 
182  if (_label.isEmpty()) {
183  switch (errorData.userType()) {
184  case QMetaType::QDateTime:
185  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as date and time.");
186  break;
187  case QMetaType::QTime:
188  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as time.");
189  break;
190  case QMetaType::QDate:
191  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as date.");
192  break;
193  default:
194  error = validationDataError(c);
195  break;
196  }
197  } else {
198  switch (errorData.userType()) {
199  case QMetaType::QDateTime:
200  //: %1 will be replaced by the field label
201  error = c->translate("Cutelyst::ValidatorAfter", "The value in the “%1” field could not be parsed as date and time.").arg(_label);
202  break;
203  case QMetaType::QTime:
204  //: %1 will be replaced by the field label
205  error = c->translate("Cutelyst::ValidatorAfter", "The value in the “%1” field could not be parsed as time.").arg(_label);
206  break;
207  case QMetaType::QDate:
208  //: %1 will be replaced by the field label
209  error = c->translate("Cutelyst::ValidatorAfter", "The value in the “%1” field could not be parsed as date.").arg(_label);
210  break;
211  default:
212  error = validationDataError(c);
213  break;
214  }
215  }
216  }
217 
218  return error;
219 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if validation failed.
QString toString(Qt::DateFormat format) const const
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occured while parsing input.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
QString toString(Qt::DateFormat format) const const
QString toString(Qt::DateFormat format) const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
Stores custom error messages and the input field label.
QDateTime toDateTime() const const
QTime toTime() const const
bool isValid() const const
Checks if a date, time or datetime is after a comparison value.
The Cutelyst Context.
Definition: context.h:38
QString timeFormat(QLocale::FormatType format) const const
bool isEmpty() const const
~ValidatorAfter() override
Deconstructs the after validator.
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:471
bool isValid() const const
QString genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if the input value could not be parsed.
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
Base class for all validator rules.
QLocale locale() const noexcept
Definition: context.cpp:447
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
ValidatorAfter(const QString &field, const QVariant &comparison, const QString &timeZone=QString(), const char *inputFormat=nullptr, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new after validator.
int userType() const const
void setValue(const T &value)
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
bool isValid() const const
QString dateFormat(QLocale::FormatType format) const const
QDate toDate() const const
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if comparison data was invalid.
QString field() const
Returns the name of the field to validate.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49
QString dateTimeFormat(QLocale::FormatType format) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void defaultValue(Context *c, ValidatorReturnType *result, const char *validatorName) const
I a defValKey has been set in the constructor, this will try to get the default value from the stash ...