cutelyst  3.9.1
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 }
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 occurred 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
Stores custom error messages and the input field label.
QDateTime toDateTime() const const
QTime toTime() const const
bool isValid() const const
The Cutelyst Context.
Definition: context.h:38
QString timeFormat(QLocale::FormatType format) const const
bool isEmpty() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:490
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if comparison data was invalid.
bool isValid() const const
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.
Checks if a date, time or datetime is before a comparison value.
QLocale locale() const noexcept
Definition: context.cpp:466
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
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 arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString field() const
Returns the name of the field to validate.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49
~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.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
QString dateTimeFormat(QLocale::FormatType format) 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 ...