cutelyst  5.0.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-2025 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 
13  const QVariant &comparison,
14  const QString &timeZone,
15  const char *inputFormat,
16  const ValidatorMessages &messages,
17  const QString &defValKey)
18  : ValidatorRule(*new ValidatorBeforePrivate(field,
19  comparison,
20  timeZone,
21  inputFormat,
22  messages,
23  defValKey))
24 {
25 }
26 
28 
30 {
31  ValidatorReturnType result;
32 
33  Q_D(const ValidatorBefore);
34 
35  const QString v = value(params);
36 
37  if (!v.isEmpty()) {
38 
39  const QTimeZone tz = ValidatorBeforePrivate::extractTimeZone(c, params, d->timeZone);
40 
41  const QVariant _comp =
42  (d->comparison.userType() == QMetaType::QString)
43  ? d->extractOtherDateTime(c, params, d->comparison.toString(), tz, d->inputFormat)
44  : d->comparison;
45 
46  if (_comp.userType() == QMetaType::QDate) {
47 
48  const QDate odate = _comp.toDate();
49  if (Q_UNLIKELY(!odate.isValid())) {
50  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison date";
52  } else {
53  const QDate date = d->extractDate(c, v, d->inputFormat);
54  if (Q_UNLIKELY(!date.isValid())) {
55  qCWarning(C_VALIDATOR).noquote().nospace()
56  << debugString(c) << " Can not parse input date \"" << v << "\"";
57  result.errorMessage = parsingError(c, odate);
58  } else {
59  if (Q_UNLIKELY(date >= odate)) {
60  qCDebug(C_VALIDATOR).noquote()
61  << debugString(c) << "Input" << date << "is not before" << odate;
62  result.errorMessage = validationError(c, odate);
63  } else {
64  result.value.setValue(date);
65  }
66  }
67  }
68 
69  } else if (_comp.userType() == QMetaType::QDateTime) {
70 
71  const QDateTime odatetime = _comp.toDateTime();
72  if (Q_UNLIKELY(!odatetime.isValid())) {
73  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison datetime";
75  } else {
76  const QDateTime datetime = d->extractDateTime(c, v, d->inputFormat, tz);
77  if (Q_UNLIKELY(!datetime.isValid())) {
78  qCWarning(C_VALIDATOR).noquote().nospace()
79  << debugString(c) << " Can not parse input datetime \"" << v << "\"";
80  result.errorMessage = parsingError(c, odatetime);
81  } else {
82  if (Q_UNLIKELY(datetime >= odatetime)) {
83  qCDebug(C_VALIDATOR).noquote() << debugString(c) << "Input" << datetime
84  << "is not before" << odatetime;
85  result.errorMessage = validationError(c, odatetime);
86  } else {
87  result.value.setValue(datetime);
88  }
89  }
90  }
91 
92  } else if (_comp.userType() == QMetaType::QTime) {
93 
94  const QTime otime = _comp.toTime();
95  if (Q_UNLIKELY(!otime.isValid())) {
96  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison time";
98  } else {
99  const QTime time = d->extractTime(c, v, d->inputFormat);
100  if (Q_UNLIKELY(!time.isValid())) {
101  qCWarning(C_VALIDATOR).noquote().nospace()
102  << debugString(c) << " Can not parse input time \"" << v << "\"";
103  result.errorMessage = parsingError(c, otime);
104  } else {
105  if (Q_UNLIKELY(time >= otime)) {
106  qCDebug(C_VALIDATOR).noquote()
107  << debugString(c) << "Input" << time << "is not before" << otime;
108  result.errorMessage = validationError(c, otime);
109  } else {
110  result.value.setValue(time);
111  }
112  }
113  }
114 
115  } else {
116  qCWarning(C_VALIDATOR).noquote()
117  << debugString(c) << "Invalid comparison data:" << d->comparison;
118  result.errorMessage = validationDataError(c);
119  }
120  } else {
121  defaultValue(c, &result);
122  }
123 
124  return result;
125 }
126 
128 {
129  cb(validate(c, params));
130 }
131 
133  const QVariant &errorData) const
134 {
135  const QString _label = label(c);
136  if (_label.isEmpty()) {
137 
138  switch (errorData.userType()) {
139  case QMetaType::QDate:
140  //: %1 will be replaced by the comparison date in short format
141  //% "Has to be before %1."
142  return c->qtTrId("cutelyst-valbefore-genvalerr-date")
143  .arg(c->locale().toString(errorData.toDate(), QLocale::ShortFormat));
145  //: %1 will be replaced by the comparison datetime in short format
146  //% "Has to be before %1."
147  return c->qtTrId("cutelyst-valbefore-genvalerr-dt")
148  .arg(c->locale().toString(errorData.toDateTime(), QLocale::ShortFormat));
149  case QMetaType::QTime:
150  //: %1 will be replaced by the comparison time in short format
151  //% "Has to be before %1."
152  return c->qtTrId("cutelyst-valbefore-genvalerr-time")
153  .arg(c->locale().toString(errorData.toTime(), QLocale::ShortFormat));
154  default:
155  return validationDataError(c);
156  }
157 
158  } else {
159 
160  switch (errorData.userType()) {
161  case QMetaType::QDate:
162  //: %1 will be replaced by the field label, %2 by the comparison date in short format
163  //% "The date in the “%1” field must be before %2."
164  return c->qtTrId("cutelyst-valbefore-genvalerr-date-label")
165  .arg(_label, c->locale().toString(errorData.toDate(), QLocale::ShortFormat));
167  //: %1 will be replaced by the field label, %2 by the comparison datetime in short
168  //: format
169  //% "The date and time in the “%1” field must be before %2."
170  return c->qtTrId("cutelyst-valbefore-genvalerr-dt-label")
171  .arg(_label, c->locale().toString(errorData.toDateTime(), QLocale::ShortFormat));
172  case QMetaType::QTime:
173  //: %1 will be replaced by the field label, %2 by the comparison time in short format
174  //% "The time in the “%1” field must be before %2."
175  return c->qtTrId("cutelyst-valbefore-genvalerr-time-label")
176  .arg(_label, c->locale().toString(errorData.toTime(), QLocale::ShortFormat));
177  default:
178  return validationDataError(c);
179  }
180  }
181 }
182 
184 {
185  Q_UNUSED(errorData)
186  const QString _label = label(c);
187  // the translation strings are defined in ValidatorAfter
188  if (_label.isEmpty()) {
189  return c->qtTrId("cutelyst-validator-genvaldataerr-dt");
190  } else {
191  return c->qtTrId("cutelyst-validator-genvaldataerr-dt-label").arg(_label);
192  }
193 }
194 
196 {
197  Q_D(const ValidatorBefore);
198 
199  // translation strings are defined in ValidatorAfter
200 
201  const QString _label = label(c);
202  if (d->inputFormat) {
203  const QString _inputFormatTranslated =
204  d->translationContext ? c->translate(d->translationContext, d->inputFormat)
205  : c->qtTrId(d->inputFormat);
206  if (_label.isEmpty()) {
207  return c->qtTrId("cutelyst-validator-genparseerr-dt-format")
208  .arg(_inputFormatTranslated);
209  } else {
210  return c->qtTrId("cutelyst-validator-genparseerr-dt-format-label")
211  .arg(_label, _inputFormatTranslated);
212  }
213  } else {
214 
215  if (_label.isEmpty()) {
216  switch (errorData.userType()) {
218  return c->qtTrId("cutelyst-validator-genparseerr-dt");
219  case QMetaType::QTime:
220  return c->qtTrId("cutelyst-validator-genparseerr-time");
221  case QMetaType::QDate:
222  return c->qtTrId("cutelyst-validator-genparseerr-date");
223  default:
224  return validationDataError(c);
225  }
226  } else {
227  switch (errorData.userType()) {
229  return c->qtTrId("cutelyst-vaidator-genparseerr-dt-label").arg(_label);
230  case QMetaType::QTime:
231  return c->qtTrId("cutelyst-validator-genparseerr-time-label").arg(_label);
232  case QMetaType::QDate:
233  return c->qtTrId("cutelyst-validator-genparseerr-date-label").arg(_label);
234  default:
235  return validationDataError(c);
236  }
237  }
238  }
239 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Stores custom error messages and the input field label.
ValidatorBefore(const QString &field, const QVariant &comparison, const QString &timeZone={}, const char *inputFormat=nullptr, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey={})
QDateTime toDateTime() const const
QTime toTime() const const
QString toString(QDate date, FormatType format) const const
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 genericValidationDataError(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.
Checks if a date, time or datetime is before a comparison value.
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
QString validationError(Context *c, const QVariant &errorData={}) const
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 genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
void validateCb(Context *c, const ParamsMultiMap &params, ValidatorRtFn cb) const override
QString arg(Args &&... args) const const
void setValue(QVariant &&value)