cutelyst 3.9.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-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
11using namespace Cutelyst;
12
13ValidatorAfter::ValidatorAfter(const QString &field,
14 const QVariant &comparison,
15 const QString &timeZone,
16 const char *inputFormat,
17 const Cutelyst::ValidatorMessages &messages,
18 const QString &defValKey)
20 *new ValidatorAfterPrivate(field, comparison, timeZone, inputFormat, messages, defValKey))
21{
22}
23
25{
26}
27
29{
31
32 Q_D(const ValidatorAfter);
33
34 const QString v = value(params);
35
36 if (!v.isEmpty()) {
37
38 const QTimeZone tz = d->extractTimeZone(c, params, d->timeZone);
39
40 const QVariant _comp =
41 (d->comparison.userType() == QMetaType::QString)
42 ? d->extractOtherDateTime(c, params, d->comparison.toString(), tz, d->inputFormat)
43 : d->comparison;
44
45 if (_comp.userType() == QMetaType::QDate) {
46
47 const QDate odate = _comp.toDate();
48 if (Q_UNLIKELY(!odate.isValid())) {
49 qCWarning(
50 C_VALIDATOR,
51 "ValidatorAfter: Invalid comparison date and time for field %s at %s::%s.",
52 qPrintable(field()),
53 qPrintable(c->controllerName()),
54 qPrintable(c->actionName()));
56 } else {
57 const QDate date = d->extractDate(c, v, d->inputFormat);
58 if (Q_UNLIKELY(!date.isValid())) {
59 qCWarning(
60 C_VALIDATOR,
61 "ValidatorAfter: Can not parse input date \"%s\" for field %s at %s::%s.",
62 qPrintable(v),
63 qPrintable(field()),
64 qPrintable(c->controllerName()),
65 qPrintable(c->actionName()));
66 result.errorMessage = parsingError(c, odate);
67 } else {
68 if (Q_UNLIKELY(date <= odate)) {
69 qCDebug(C_VALIDATOR,
70 "ValidatorAfter: Validation failed at %s::%s for field %s: Input "
71 "date \"%s\" is not after \"%s\".",
72 qPrintable(c->controllerName()),
73 qPrintable(c->actionName()),
74 qPrintable(field()),
75 qPrintable(date.toString()),
76 qPrintable(odate.toString()));
77 result.errorMessage = validationError(c, odate);
78 } else {
79 result.value.setValue(date);
80 }
81 }
82 }
83
84 } else if (_comp.userType() == QMetaType::QDateTime) {
85
86 const QDateTime odatetime = _comp.toDateTime();
87 if (Q_UNLIKELY(!odatetime.isValid())) {
88 qCWarning(
89 C_VALIDATOR,
90 "ValidatorAfter: Invalid comparison date and time for field %s at %s::%s.",
91 qPrintable(field()),
92 qPrintable(c->controllerName()),
93 qPrintable(c->actionName()));
95 } else {
96 const QDateTime datetime = d->extractDateTime(c, v, d->inputFormat, tz);
97 if (Q_UNLIKELY(!datetime.isValid())) {
98 qCWarning(C_VALIDATOR,
99 "ValidatorAfter: Can not parse input date and time \"%s\" for field "
100 "%s at %s::%s.",
101 qPrintable(v),
102 qPrintable(field()),
103 qPrintable(c->controllerName()),
104 qPrintable(c->actionName()));
105 result.errorMessage = parsingError(c, odatetime);
106 } else {
107 if (Q_UNLIKELY(datetime <= odatetime)) {
108 qCDebug(C_VALIDATOR,
109 "ValidatorAfter: Validation failed at %s::%s for field %s: Input "
110 "date and time \"%s\" is not after \"%s\".",
111 qPrintable(c->controllerName()),
112 qPrintable(c->actionName()),
113 qPrintable(field()),
114 qPrintable(datetime.toString()),
115 qPrintable(odatetime.toString()));
116 result.errorMessage = validationError(c, odatetime);
117 } else {
118 result.value.setValue(datetime);
119 }
120 }
121 }
122
123 } else if (_comp.userType() == QMetaType::QTime) {
124
125 const QTime otime = _comp.toTime();
126 if (Q_UNLIKELY(!otime.isValid())) {
127 qCWarning(C_VALIDATOR,
128 "ValidatorAfter: Invalid comparison time for field %s at %s::%s.",
129 qPrintable(field()),
130 qPrintable(c->controllerName()),
131 qPrintable(c->actionName()));
133 } else {
134 const QTime time = d->extractTime(c, v, d->inputFormat);
135 if (Q_UNLIKELY(!time.isValid())) {
136 qCWarning(
137 C_VALIDATOR,
138 "ValidatorAfter: Can not parse input time \"%s\" for field %s at %s::%s.",
139 qPrintable(v),
140 qPrintable(field()),
141 qPrintable(c->controllerName()),
142 qPrintable(c->actionName()));
143 result.errorMessage = parsingError(c, otime);
144 } else {
145 if (Q_UNLIKELY(time <= otime)) {
146 qCDebug(C_VALIDATOR,
147 "ValidatorAfter: Validation failed at %s::%s for field %s: Input "
148 "time \"%s\" is not after \"%s\".",
149 qPrintable(c->controllerName()),
150 qPrintable(c->actionName()),
151 qPrintable(field()),
152 qPrintable(time.toString()),
153 qPrintable(otime.toString()));
154 result.errorMessage = validationError(c, otime);
155 } else {
156 result.value.setValue(time);
157 }
158 }
159 }
160
161 } else {
162 qCWarning(C_VALIDATOR)
163 << "ValidatorAfter: Invalid validation data for field" << field() << "at"
164 << c->controllerName() << "::" << c->actionName() << ":" << d->comparison;
166 }
167 } else {
168 defaultValue(c, &result, "ValidatorAfter");
169 }
170
171 return result;
172}
173
175 const QVariant &errorData) const
176{
177 QString error;
178
179 const QString _label = label(c);
180 if (_label.isEmpty()) {
181
182 switch (errorData.userType()) {
183 case QMetaType::QDate:
184 error =
185 QStringLiteral("Has to be after %1.")
186 .arg(errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
187 break;
188 case QMetaType::QDateTime:
189 error = QStringLiteral("Has to be after %1.")
190 .arg(errorData.toDateTime().toString(
191 c->locale().dateTimeFormat(QLocale::ShortFormat)));
192 break;
193 case QMetaType::QTime:
194 error =
195 QStringLiteral("Has to be after %1.")
196 .arg(errorData.toTime().toString(c->locale().timeFormat(QLocale::ShortFormat)));
197 break;
198 default:
199 error = validationDataError(c);
200 break;
201 }
202
203 } else {
204
205 switch (errorData.userType()) {
206 case QMetaType::QDate:
207 error =
208 c->translate("Cutelyst::ValidatorAfter",
209 "The date in the “%1” field must be after %2.")
210 .arg(_label,
211 errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
212 break;
213 case QMetaType::QDateTime:
214 error = c->translate("Cutelyst::ValidatorAfter",
215 "The date and time in the “%1” field must be after %2.")
216 .arg(_label,
217 errorData.toDateTime().toString(
218 c->locale().dateTimeFormat(QLocale::ShortFormat)));
219 break;
220 case QMetaType::QTime:
221 error =
222 c->translate("Cutelyst::ValidatorAfter",
223 "The time in the “%1” field must be after %2.")
224 .arg(_label,
225 errorData.toTime().toString(c->locale().timeFormat(QLocale::ShortFormat)));
226 break;
227 default:
228 error = validationDataError(c);
229 break;
230 }
231 }
232
233 return error;
234}
235
236QString ValidatorAfter::genericValidationDataError(Context *c, const QVariant &errorData) const
237{
238 QString error;
239
240 Q_UNUSED(errorData)
241 error =
242 c->translate("Cutelyst::ValidatorAfter",
243 "The comparison value is not a valid date and/or time, or cannot be found.");
244
245 return error;
246}
247
248QString ValidatorAfter::genericParsingError(Context *c, const QVariant &errorData) const
249{
250 QString error;
251
252 Q_D(const ValidatorAfter);
253
254 const QString _label = label(c);
255 if (d->inputFormat) {
256 if (_label.isEmpty()) {
257 error =
258 c->translate(
259 "Cutelyst::ValidatorAfter",
260 "Could not be parsed according to the following date and/or time format: %1")
261 .arg(c->translate(d->translationContext.data(), d->inputFormat));
262 } else {
263 error = c->translate("Cutelyst::ValidatorAfter",
264 "The value of the “%1” field could not be parsed according to the "
265 "following date and/or time format: %2")
266 .arg(_label, c->translate(d->translationContext.data(), d->inputFormat));
267 }
268 } else {
269
270 if (_label.isEmpty()) {
271 switch (errorData.userType()) {
272 case QMetaType::QDateTime:
273 error = c->translate("Cutelyst::ValidatorAfter",
274 "Could not be parsed as date and time.");
275 break;
276 case QMetaType::QTime:
277 error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as time.");
278 break;
279 case QMetaType::QDate:
280 error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as date.");
281 break;
282 default:
283 error = validationDataError(c);
284 break;
285 }
286 } else {
287 switch (errorData.userType()) {
288 case QMetaType::QDateTime:
289 //: %1 will be replaced by the field label
290 error = c->translate(
291 "Cutelyst::ValidatorAfter",
292 "The value in the “%1” field could not be parsed as date and time.")
293 .arg(_label);
294 break;
295 case QMetaType::QTime:
296 //: %1 will be replaced by the field label
297 error = c->translate("Cutelyst::ValidatorAfter",
298 "The value in the “%1” field could not be parsed as time.")
299 .arg(_label);
300 break;
301 case QMetaType::QDate:
302 //: %1 will be replaced by the field label
303 error = c->translate("Cutelyst::ValidatorAfter",
304 "The value in the “%1” field could not be parsed as date.")
305 .arg(_label);
306 break;
307 default:
308 error = validationDataError(c);
309 break;
310 }
311 }
312 }
313
314 return error;
315}
The Cutelyst Context.
Definition context.h:39
QLocale locale() const noexcept
Definition context.cpp:466
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition context.cpp:490
Checks if a date, time or datetime is after a comparison value.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
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.
~ValidatorAfter() override
Deconstructs the after validator.
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if comparison data was invalid.
QString genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if the input value could not be parsed.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if validation failed.
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
QMultiMap< QString, QString > ParamsMultiMap
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.