cutelyst  5.0.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatorafter.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2025 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 
14  const QVariant &comparison,
15  const QString &timeZone,
16  const char *inputFormat,
17  const Cutelyst::ValidatorMessages &messages,
18  const QString &defValKey)
19  : ValidatorRule(
20  *new ValidatorAfterPrivate(field, comparison, timeZone, inputFormat, messages, defValKey))
21 {
22 }
23 
25 
27 {
28  ValidatorReturnType result;
29 
30  Q_D(const ValidatorAfter);
31 
32  const QString v = value(params);
33 
34  if (!v.isEmpty()) {
35 
36  const QTimeZone tz = ValidatorAfterPrivate::extractTimeZone(c, params, d->timeZone);
37 
38  const QVariant _comp =
39  (d->comparison.userType() == QMetaType::QString)
40  ? d->extractOtherDateTime(c, params, d->comparison.toString(), tz, d->inputFormat)
41  : d->comparison;
42 
43  if (_comp.userType() == QMetaType::QDate) {
44 
45  const QDate odate = _comp.toDate();
46  if (Q_UNLIKELY(!odate.isValid())) {
47  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison date";
49  } else {
50  const QDate date = d->extractDate(c, v, d->inputFormat);
51  if (Q_UNLIKELY(!date.isValid())) {
52  qCWarning(C_VALIDATOR).noquote().nospace()
53  << debugString(c) << " Can not parse input date \"" << v << "\"";
54  result.errorMessage = parsingError(c, odate);
55  } else {
56  if (Q_UNLIKELY(date <= odate)) {
57  qCDebug(C_VALIDATOR).noquote()
58  << debugString(c) << "Input" << date << "is not after" << odate;
59  result.errorMessage = validationError(c, odate);
60  } else {
61  result.value.setValue(date);
62  }
63  }
64  }
65 
66  } else if (_comp.userType() == QMetaType::QDateTime) {
67 
68  const QDateTime odatetime = _comp.toDateTime();
69  if (Q_UNLIKELY(!odatetime.isValid())) {
70  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison datetime";
72  } else {
73  const QDateTime datetime = d->extractDateTime(c, v, d->inputFormat, tz);
74  if (Q_UNLIKELY(!datetime.isValid())) {
75  qCWarning(C_VALIDATOR).noquote().nospace()
76  << debugString(c) << " Can not parse input datetime \"" << v << "\"";
77  result.errorMessage = parsingError(c, odatetime);
78  } else {
79  if (Q_UNLIKELY(datetime <= odatetime)) {
80  qCDebug(C_VALIDATOR).noquote()
81  << debugString(c) << "Input" << datetime << "is not after" << odatetime;
82  result.errorMessage = validationError(c, odatetime);
83  } else {
84  result.value.setValue(datetime);
85  }
86  }
87  }
88 
89  } else if (_comp.userType() == QMetaType::QTime) {
90 
91  const QTime otime = _comp.toTime();
92  if (Q_UNLIKELY(!otime.isValid())) {
93  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison time";
95  } else {
96  const QTime time = d->extractTime(c, v, d->inputFormat);
97  if (Q_UNLIKELY(!time.isValid())) {
98  qCWarning(C_VALIDATOR).noquote().nospace()
99  << debugString(c) << " Can not parse input time \"" << v << "\"";
100  result.errorMessage = parsingError(c, otime);
101  } else {
102  if (Q_UNLIKELY(time <= otime)) {
103  qCDebug(C_VALIDATOR).noquote()
104  << debugString(c) << "Input" << time << "is not after" << otime;
105  result.errorMessage = validationError(c, otime);
106  } else {
107  result.value.setValue(time);
108  }
109  }
110  }
111 
112  } else {
113  qCWarning(C_VALIDATOR).noquote()
114  << debugString(c) << "Invalid comparison data:" << d->comparison;
115  result.errorMessage = validationDataError(c);
116  }
117  } else {
118  defaultValue(c, &result);
119  }
120 
121  return result;
122 }
123 
125 {
126  cb(validate(c, params));
127 }
128 
130  const QVariant &errorData) const
131 {
132  const QString _label = label(c);
133  if (_label.isEmpty()) {
134 
135  switch (errorData.userType()) {
136  case QMetaType::QDate:
137  //: %1 will be replaced by the comparison date in short format
138  //% "Has to be after %1."
139  return c->qtTrId("cutelyst-valafter-genvalerr-date")
140  .arg(c->locale().toString(errorData.toDate(), QLocale::ShortFormat));
142  //: %1 will be replaced by the comparison datetime in short format
143  //% "Has to be after %1."
144  return c->qtTrId("cutelyst-valafter-genvalerr-dt")
145  .arg(c->locale().toString(errorData.toDateTime(), QLocale::ShortFormat));
146  case QMetaType::QTime:
147  //: %1 will be replaced by the comparison time in short format
148  //% "Has to be after %1."
149  return c->qtTrId("cutelyst-valafter-genvalerr-time")
150  .arg(c->locale().toString(errorData.toTime(), QLocale::ShortFormat));
151  default:
152  return validationDataError(c);
153  }
154 
155  } else {
156 
157  switch (errorData.userType()) {
158  case QMetaType::QDate:
159  //: %1 will be rplaced by the field label, %2 by the comparison date in short format
160  //% "The date in the “%1” field must be after %2."
161  return c->qtTrId("cutelyst-valafter-genvalerr-date-label")
162  .arg(_label, c->locale().toString(errorData.toDate(), QLocale::ShortFormat));
164  //: %1 will be replaced by the field label, %2 by the comparison datetime in short
165  //: format
166  //% "The date and time in the “%1” field must be after %2."
167  return c->qtTrId("cutelyst-valafter-genvalerr-dt-label")
168  .arg(_label, c->locale().toString(errorData.toDateTime(), QLocale::ShortFormat));
169  case QMetaType::QTime:
170  //: %1 will be replaced by the field label, %2 by the comparison time in short format
171  //% "The time in the “%1” field must be after %2."
172  return c->qtTrId("cutelyst-valafter-genvalerr-time-label")
173  .arg(_label, c->locale().toString(errorData.toTime(), QLocale::ShortFormat));
174  default:
175  return validationDataError(c);
176  }
177  }
178 }
179 
181 {
182  Q_UNUSED(errorData)
183  const QString _label = label(c);
184  if (_label.isEmpty()) {
185  //% "The comparison value is not a valid date and/or time, or can not be found."
186  return c->qtTrId("cutelyst-validator-genvaldataerr-dt");
187  } else {
188  //: %1 will be replaced by the field label
189  //% "The comparison value for the “%1” field is not a valid date and/or time, or "
190  //% "can not be found."
191  return c->qtTrId("cutelyst-validator-genvaldataerr-dt-label").arg(_label);
192  }
193 }
194 
196 {
197  Q_D(const ValidatorAfter);
198 
199  const QString _label = label(c);
200  if (d->inputFormat) {
201  const QString _inputFormatTranslated =
202  d->translationContext ? c->translate(d->translationContext, d->inputFormat)
203  : c->qtTrId(d->inputFormat);
204  if (_label.isEmpty()) {
205  //: %1 will be replaced by the required input format
206  //% "Could not be parsed according to the following date and/or time format: %1"
207  return c->qtTrId("cutelyst-validator-genparseerr-dt-format")
208  .arg(_inputFormatTranslated);
209  } else {
210  //: %1 will be replaced by the field label, %2 by the required input format
211  //% "The value of the “%1” field could not be parsed according to the "
212  //% "following date and/or time format: %2"
213  return c->qtTrId("cutelyst-validator-genparseerr-dt-format-label")
214  .arg(_label, _inputFormatTranslated);
215  }
216  } else {
217 
218  if (_label.isEmpty()) {
219  switch (errorData.userType()) {
221  //% "Could not be parsed as date and time."
222  return c->qtTrId("cutelyst-validator-genparseerr-dt");
223  case QMetaType::QTime:
224  //% "Could not be parsed as time."
225  return c->qtTrId("cutelyst-validator-genparseerr-time");
226  case QMetaType::QDate:
227  //% "Could not be parsed as date."
228  return c->qtTrId("cutelyst-validator-genparseerr-date");
229  default:
230  return validationDataError(c);
231  }
232  } else {
233  switch (errorData.userType()) {
235  //: %1 will be replaced by the field label
236  //% "The value in the “%1” field could not be parsed as date and time."
237  return c->qtTrId("cutelyst-vaidator-genparseerr-dt-label").arg(_label);
238  case QMetaType::QTime:
239  //: %1 will be replaced by the field label
240  //% "The value in the “%1” field could not be parsed as time."
241  return c->qtTrId("cutelyst-validator-genparseerr-time-label").arg(_label);
242  case QMetaType::QDate:
243  //: %1 will be replaced by the field label
244  //% "The value in the “%1” field could not be parsed as date."
245  return c->qtTrId("cutelyst-validator-genparseerr-date-label").arg(_label);
246  default:
247  return validationDataError(c);
248  }
249  }
250  }
251 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Stores custom error messages and the input field label.
QDateTime toDateTime() const const
QTime toTime() const const
void validateCb(Context *c, const ParamsMultiMap &params, ValidatorRtFn cb) const override
QString toString(QDate date, FormatType format) const const
Checks if a date, time or datetime is after a comparison value.
bool isValid(int year, int month, int day)
The Cutelyst Context.
Definition: context.h:42
void defaultValue(Context *c, ValidatorReturnType *result) const
bool isEmpty() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:485
QString genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
bool isValid(int h, int m, int s, int ms)
QString parsingError(Context *c, const QVariant &errorData={}) const
The Cutelyst namespace holds all public Cutelyst API.
QString debugString(const Context *c) const
Base class for all validator rules.
QLocale locale() const noexcept
Definition: context.cpp:461
int userType() const const
QString value(const ParamsMultiMap &params) const
bool isValid() const const
QString label(const Context *c) const
std::function< void(ValidatorReturnType &&result)> ValidatorRtFn
Void callback function for validator rules that processes the ValidatorReturnType.
Definition: validatorrule.h:82
QDate toDate() const const
ValidatorAfter(const QString &field, const QVariant &comparison, const QString &timeZone={}, const char *inputFormat=nullptr, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey={})
QString validationError(Context *c, const QVariant &errorData={}) const
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
QString validationDataError(Context *c, const QVariant &errorData={}) const
QString qtTrId(const char *id, int n=-1) const
Definition: context.h:658
Contains the result of a single input parameter validation.
Definition: validatorrule.h:52
QString arg(Args &&... args) const const
void setValue(QVariant &&value)