cutelyst  3.9.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatorbefore.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2022 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatorbefore_p.h"
7 
8 #include <QtCore/QLoggingCategory>
9 
10 using namespace Cutelyst;
11 
12 Q_LOGGING_CATEGORY(C_VALIDATORBEFORE, "cutelyst.utils.validator.before", QtWarningMsg)
13 
15  const QVariant &comparison,
16  const QString &timeZone,
17  const char *inputFormat,
18  const ValidatorMessages &messages,
19  const QString &defValKey)
20  : ValidatorRule(*new ValidatorBeforePrivate(field,
21  comparison,
22  timeZone,
23  inputFormat,
24  messages,
25  defValKey))
26 {
27 }
28 
30 {
31 }
32 
34 {
35  ValidatorReturnType result;
36 
37  Q_D(const ValidatorBefore);
38 
39  const QString v = value(params);
40 
41  if (!v.isEmpty()) {
42 
43  const QTimeZone tz = d->extractTimeZone(c, params, d->timeZone);
44 
45  const QVariant _comp =
46  (d->comparison.userType() == QMetaType::QString)
47  ? d->extractOtherDateTime(c, params, d->comparison.toString(), tz, d->inputFormat)
48  : d->comparison;
49 
50  if (_comp.userType() == QMetaType::QDate) {
51 
52  const QDate odate = _comp.toDate();
53  if (Q_UNLIKELY(!odate.isValid())) {
54  qCWarning(
55  C_VALIDATOR,
56  "ValidatorBefore: Invalid comparison date and time for field %s at %s::%s.",
57  qPrintable(field()),
58  qPrintable(c->controllerName()),
59  qPrintable(c->actionName()));
61  } else {
62  const QDate date = d->extractDate(c, v, d->inputFormat);
63  if (Q_UNLIKELY(!date.isValid())) {
64  qCWarning(
65  C_VALIDATOR,
66  "ValidatorBefore: Can not parse input date \"%s\" for field %s at %s::%s.",
67  qPrintable(v),
68  qPrintable(field()),
69  qPrintable(c->controllerName()),
70  qPrintable(c->actionName()));
71  result.errorMessage = parsingError(c, odate);
72  } else {
73  if (Q_UNLIKELY(date >= odate)) {
74  qCDebug(C_VALIDATOR,
75  "ValidatorBefore: Validation failed at %s::%s for field %s: Input "
76  "date \"%s\" is not before \"%s\".",
77  qPrintable(c->controllerName()),
78  qPrintable(c->actionName()),
79  qPrintable(field()),
80  qPrintable(date.toString()),
81  qPrintable(odate.toString()));
82  result.errorMessage = validationError(c, odate);
83  } else {
84  result.value.setValue(date);
85  }
86  }
87  }
88 
89  } else if (_comp.userType() == QMetaType::QDateTime) {
90 
91  const QDateTime odatetime = _comp.toDateTime();
92  if (Q_UNLIKELY(!odatetime.isValid())) {
93  qCWarning(
94  C_VALIDATOR,
95  "ValidatorBefore: Invalid comparison date and time for field %s at %s::%s.",
96  qPrintable(field()),
97  qPrintable(c->controllerName()),
98  qPrintable(c->actionName()));
100  } else {
101  const QDateTime datetime = d->extractDateTime(c, v, d->inputFormat, tz);
102  if (Q_UNLIKELY(!datetime.isValid())) {
103  qCWarning(C_VALIDATOR,
104  "ValidatorBefore: Can not parse input date and time \"%s\" for field "
105  "%s at %s::%s.",
106  qPrintable(v),
107  qPrintable(field()),
108  qPrintable(c->controllerName()),
109  qPrintable(c->actionName()));
110  result.errorMessage = parsingError(c, odatetime);
111  } else {
112  if (Q_UNLIKELY(datetime >= odatetime)) {
113  qCDebug(C_VALIDATOR,
114  "ValidatorBefore: Validation failed at %s::%s for field %s: Input "
115  "date and time \"%s\" is not before \"%s\".",
116  qPrintable(c->controllerName()),
117  qPrintable(c->actionName()),
118  qPrintable(field()),
119  qPrintable(datetime.toString()),
120  qPrintable(odatetime.toString()));
121  result.errorMessage = validationError(c, odatetime);
122  } else {
123  result.value.setValue(datetime);
124  }
125  }
126  }
127 
128  } else if (_comp.userType() == QMetaType::QTime) {
129 
130  const QTime otime = _comp.toTime();
131  if (Q_UNLIKELY(!otime.isValid())) {
132  qCWarning(C_VALIDATOR,
133  "ValidatorBefore: Invalid comparison time for field %s at %s::%s.",
134  qPrintable(field()),
135  qPrintable(c->controllerName()),
136  qPrintable(c->actionName()));
137  result.errorMessage = validationDataError(c);
138  } else {
139  const QTime time = d->extractTime(c, v, d->inputFormat);
140  if (Q_UNLIKELY(!time.isValid())) {
141  qCWarning(
142  C_VALIDATOR,
143  "ValidatorBefore: Can not parse input time \"%s\" for field %s at %s::%s.",
144  qPrintable(v),
145  qPrintable(field()),
146  qPrintable(c->controllerName()),
147  qPrintable(c->actionName()));
148  result.errorMessage = parsingError(c, otime);
149  } else {
150  if (Q_UNLIKELY(time >= otime)) {
151  qCDebug(C_VALIDATOR,
152  "ValidatorBefore: Validation failed at %s::%s for field %s: Input "
153  "time \"%s\" is not before \"%s\".",
154  qPrintable(c->controllerName()),
155  qPrintable(c->actionName()),
156  qPrintable(field()),
157  qPrintable(time.toString()),
158  qPrintable(otime.toString()));
159  result.errorMessage = validationError(c, otime);
160  } else {
161  result.value.setValue(time);
162  }
163  }
164  }
165 
166  } else {
167  qCWarning(C_VALIDATOR)
168  << "ValidatorBefore: Invalid validation data for field" << field() << "at"
169  << c->controllerName() << "::" << c->actionName() << ":" << d->comparison;
170  result.errorMessage = validationDataError(c);
171  }
172  } else {
173  defaultValue(c, &result, "ValidatorAfter");
174  }
175 
176  return result;
177 }
178 
180  const QVariant &errorData) const
181 {
182  QString error;
183 
184  const QString _label = label(c);
185  if (_label.isEmpty()) {
186 
187  switch (errorData.userType()) {
188  case QMetaType::QDate:
189  error =
190  QStringLiteral("Has to be before %1.")
192  break;
194  error = QStringLiteral("Has to be before %1.")
195  .arg(errorData.toDateTime().toString(
197  break;
198  case QMetaType::QTime:
199  error =
200  QStringLiteral("Has to be before %1.")
202  break;
203  default:
204  error = validationDataError(c);
205  break;
206  }
207 
208  } else {
209 
210  switch (errorData.userType()) {
211  case QMetaType::QDate:
212  error =
213  c->translate("Cutelyst::ValidatorBefore",
214  "The date in the “%1” field must be before %2.")
215  .arg(_label,
217  break;
219  error = c->translate("Cutelyst::ValidatorBefore",
220  "The date and time in the “%1” field must be before %2.")
221  .arg(_label,
222  errorData.toDateTime().toString(
224  break;
225  case QMetaType::QTime:
226  error =
227  c->translate("Cutelyst::ValidatorBefore",
228  "The time in the “%1” field must be before %2.")
229  .arg(_label,
231  break;
232  default:
233  error = validationDataError(c);
234  break;
235  }
236  }
237 
238  return error;
239 }
240 
242 {
243  QString error;
244 
245  Q_UNUSED(errorData)
246  error =
247  c->translate("Cutelyst::ValidatorBefore",
248  "The comparison value is not a valid date and/or time, or cannot be found.");
249 
250  return error;
251 }
252 
254 {
255  QString error;
256 
257  Q_D(const ValidatorBefore);
258 
259  const QString _label = label(c);
260  if (d->inputFormat) {
261  if (_label.isEmpty()) {
262  //: %1 will be replaced by the datetime format
263  error =
264  c->translate(
265  "Cutelyst::ValidatorBefore",
266  "Could not be parsed according to the following date and/or time format: %1")
267  .arg(c->translate(d->translationContext.data(), d->inputFormat));
268  } else {
269  //: %1 will be replaced by the field label, %2 will be replaced by the datetime format
270  error = c->translate("Cutelyst::ValidatorBefore",
271  "The value of the “%1” field could not be parsed according to the "
272  "following date and/or time format: %2")
273  .arg(_label, c->translate(d->translationContext.data(), d->inputFormat));
274  }
275  } else {
276 
277  if (_label.isEmpty()) {
278  switch (errorData.userType()) {
280  error = c->translate("Cutelyst::ValidatorBefore",
281  "Could not be parsed as date and time.");
282  break;
283  case QMetaType::QTime:
284  error = c->translate("Cutelyst::ValidatorBefore", "Could not be parsed as time.");
285  break;
286  case QMetaType::QDate:
287  error = c->translate("Cutelyst::ValidatorBefore", "Could not be parsed as date.");
288  break;
289  default:
290  error = validationDataError(c);
291  break;
292  }
293  } else {
294  switch (errorData.userType()) {
296  //: %1 will be replaced by the field label
297  error = c->translate(
298  "Cutelyst::ValidatorBefore",
299  "The value in the “%1” field could not be parsed as date and time.")
300  .arg(_label);
301  break;
302  case QMetaType::QTime:
303  //: %1 will be replaced by the field label
304  error = c->translate("Cutelyst::ValidatorBefore",
305  "The value in the “%1” field could not be parsed as time.")
306  .arg(_label);
307  break;
308  case QMetaType::QDate:
309  //: %1 will be replaced by the field label
310  error = c->translate("Cutelyst::ValidatorBefore",
311  "The value in the “%1” field could not be parsed as date.")
312  .arg(_label);
313  break;
314  default:
315  error = validationDataError(c);
316  break;
317  }
318  }
319  }
320 
321  return error;
322 }
The Cutelyst Context.
Definition: context.h:39
QLocale locale() const noexcept
Definition: context.cpp:460
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:484
Checks if a date, time or datetime is before a comparison value.
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if comparison data was invalid.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if validation failed.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
~ValidatorBefore() override
Deconstructs the before validator.
QString genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if the input value could not be parsed.
Base class for all validator rules.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
QString field() const
Returns the name of the field to validate.
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occurred while parsing input.
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 ...
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:8
bool isValid() const const
QString toString(Qt::DateFormat format) const const
bool isValid() const const
QString toString(Qt::DateFormat format) const const
QString dateFormat(QLocale::FormatType format) const const
QString dateTimeFormat(QLocale::FormatType format) const const
QString timeFormat(QLocale::FormatType format) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool isEmpty() const const
bool isValid() const const
QString toString(Qt::DateFormat format) const const
void setValue(const T &value)
QDate toDate() const const
QDateTime toDateTime() const const
QTime toTime() const const
int userType() const const
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49