cutelyst 3.9.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatorbetween.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2017-2022 Matthias Fehring <mf@huessenbergnetz.de>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include "validatorbetween_p.h"
7
8using namespace Cutelyst;
9
11 QMetaType::Type type,
12 const QVariant &min,
13 const QVariant &max,
14 const ValidatorMessages &messages,
15 const QString &defValKey)
16 : ValidatorRule(*new ValidatorBetweenPrivate(field, type, min, max, messages, defValKey))
17{
18}
19
23
25{
27
28 const QString v = value(params);
29
30 Q_D(const ValidatorBetween);
31
32 if (!v.isEmpty()) {
33 bool ok = false;
34 bool valid = false;
35
36 switch (d->type) {
37 case QMetaType::Char:
39 case QMetaType::Int:
40 case QMetaType::Long:
42 {
43 const qlonglong val = c->locale().toLongLong(v, &ok);
44 if (Q_UNLIKELY(!ok)) {
45 result.errorMessage = parsingError(c);
46 qCWarning(
47 C_VALIDATOR,
48 "ValidatorBetween: Failed to parse value of field %s into number at %s::%s.",
49 qPrintable(field()),
50 qPrintable(c->controllerName()),
51 qPrintable(c->actionName()));
52 } else {
53 const qlonglong min = d->extractLongLong(c, params, d->min, &ok);
54 if (Q_UNLIKELY(!ok)) {
55 result.errorMessage = validationDataError(c, -1);
56 qCWarning(C_VALIDATOR,
57 "ValidatorBetween: Invalid minimum comparison value for field %s in "
58 "%s::%s.",
59 qPrintable(field()),
60 qPrintable(c->controllerName()),
61 qPrintable(c->actionName()));
62 } else {
63 const qlonglong max = d->extractLongLong(c, params, d->max, &ok);
64 if (Q_UNLIKELY(!ok)) {
65 result.errorMessage = validationDataError(c, 1);
66 qCWarning(C_VALIDATOR,
67 "ValidatorBetween: Invalid maximum comparison value for field %s "
68 "in %s::%s.",
69 qPrintable(field()),
70 qPrintable(c->controllerName()),
71 qPrintable(c->actionName()));
72 } else {
73 if ((val < min) || (val > max)) {
74 result.errorMessage =
76 QVariantMap{{QStringLiteral("val"), val},
77 {QStringLiteral("min"), min},
78 {QStringLiteral("max"), max}});
79 qCDebug(C_VALIDATOR,
80 "ValidatorBetween: Validation failed for field %s in %s::%s: "
81 "%lli is not between %lli and %lli.",
82 qPrintable(field()),
83 qPrintable(c->controllerName()),
84 qPrintable(c->actionName()),
85 val,
86 min,
87 max);
88 } else {
89 valid = true;
90 }
91 }
92 }
93 }
94 } break;
97 case QMetaType::UInt:
100 {
101 const qulonglong val = v.toULongLong(&ok);
102 if (Q_UNLIKELY(!ok)) {
103 result.errorMessage = parsingError(c);
104 qCWarning(
105 C_VALIDATOR,
106 "ValidatorBetween: Failed to parse value of field %s into number at %s::%s.",
107 qPrintable(field()),
108 qPrintable(c->controllerName()),
109 qPrintable(c->actionName()));
110 } else {
111 const qulonglong min = d->extractULongLong(c, params, d->min, &ok);
112 if (Q_UNLIKELY(!ok)) {
113 result.errorMessage = validationDataError(c, -1);
114 qCWarning(C_VALIDATOR,
115 "ValidatorBetween: Invalid minimum comparison value for field %s in "
116 "%s::%s.",
117 qPrintable(field()),
118 qPrintable(c->controllerName()),
119 qPrintable(c->actionName()));
120 } else {
121 const qulonglong max = d->extractULongLong(c, params, d->max, &ok);
122 if (Q_UNLIKELY(!ok)) {
123 result.errorMessage = validationDataError(c, 1);
124 qCWarning(C_VALIDATOR,
125 "ValidatorBetween: Invalid maximum comparison value for field %s "
126 "in %s::%s.",
127 qPrintable(field()),
128 qPrintable(c->controllerName()),
129 qPrintable(c->actionName()));
130 } else {
131 if ((val < min) || (val > max)) {
132 result.errorMessage =
134 QVariantMap{{QStringLiteral("val"), val},
135 {QStringLiteral("min"), min},
136 {QStringLiteral("max"), max}});
137 qCDebug(C_VALIDATOR,
138 "ValidatorBetween: Validation failed for field %s in %s::%s: "
139 "%llu is not between %llu and %llu.",
140 qPrintable(field()),
141 qPrintable(c->controllerName()),
142 qPrintable(c->actionName()),
143 val,
144 min,
145 max);
146 } else {
147 valid = true;
148 }
149 }
150 }
151 }
152 } break;
153 case QMetaType::Float:
155 {
156 const double val = v.toDouble(&ok);
157 if (Q_UNLIKELY(!ok)) {
158 result.errorMessage = parsingError(c);
159 qCWarning(
160 C_VALIDATOR,
161 "ValidatorBetween: Failed to parse value of field %s into number at %s::%s.",
162 qPrintable(field()),
163 qPrintable(c->controllerName()),
164 qPrintable(c->actionName()));
165 } else {
166 const double min = d->extractDouble(c, params, d->min, &ok);
167 if (Q_UNLIKELY(!ok)) {
168 result.errorMessage = validationDataError(c, -1);
169 qCWarning(C_VALIDATOR,
170 "ValidatorBetween: Invalid minimum comparison value for field %s in "
171 "%s::%s.",
172 qPrintable(field()),
173 qPrintable(c->controllerName()),
174 qPrintable(c->actionName()));
175 } else {
176 const double max = d->extractDouble(c, params, d->max, &ok);
177 if (Q_UNLIKELY(!ok)) {
178 result.errorMessage = validationDataError(c, 1);
179 qCWarning(C_VALIDATOR,
180 "ValidatorBetween: Invalid maximum comparison value for field %s "
181 "in %s::%s.",
182 qPrintable(field()),
183 qPrintable(c->controllerName()),
184 qPrintable(c->actionName()));
185 } else {
186 if ((val < min) || (val > max)) {
187 result.errorMessage =
189 QVariantMap{{QStringLiteral("val"), val},
190 {QStringLiteral("min"), min},
191 {QStringLiteral("max"), max}});
192 qCDebug(C_VALIDATOR,
193 "ValidatorBetween: Validation failed for field %s in %s::%s: "
194 "%f is not between %f and %f.",
195 qPrintable(field()),
196 qPrintable(c->controllerName()),
197 qPrintable(c->actionName()),
198 val,
199 min,
200 max);
201 } else {
202 valid = true;
203 }
204 }
205 }
206 }
207 } break;
209 {
210 const qlonglong val = static_cast<qlonglong>(v.length());
211 const qlonglong min = d->extractLongLong(c, params, d->min, &ok);
212 if (Q_UNLIKELY(!ok)) {
213 result.errorMessage = validationDataError(c, -1);
214 qCWarning(
215 C_VALIDATOR,
216 "ValidatorBetween: Invalid minimum comparison value for field %s in %s::%s.",
217 qPrintable(field()),
218 qPrintable(c->controllerName()),
219 qPrintable(c->actionName()));
220 } else {
221 const qlonglong max = d->extractLongLong(c, params, d->max, &ok);
222 if (Q_UNLIKELY(!ok)) {
223 result.errorMessage = validationDataError(c, 1);
224 qCWarning(C_VALIDATOR,
225 "ValidatorBetween: Invalid maximum comparison value for field %s in "
226 "%s::%s.",
227 qPrintable(field()),
228 qPrintable(c->controllerName()),
229 qPrintable(c->actionName()));
230 } else {
231 if ((val < min) || (val > max)) {
232 result.errorMessage =
234 QVariantMap{{QStringLiteral("val"), val},
235 {QStringLiteral("min"), min},
236 {QStringLiteral("max"), max}});
237 qCDebug(C_VALIDATOR,
238 "ValidatorBetween: Validation failed for field %s in %s::%s: "
239 "string length %lli is not between %lli and %lli.",
240 qPrintable(field()),
241 qPrintable(c->controllerName()),
242 qPrintable(c->actionName()),
243 val,
244 min,
245 max);
246 } else {
247 valid = true;
248 }
249 }
250 }
251 } break;
252 default:
253 qCWarning(C_VALIDATOR,
254 "ValidatorBetween: The comparison type with ID %i for field %s at %s::%s is "
255 "not supported.",
256 static_cast<int>(d->type),
257 qPrintable(field()),
258 qPrintable(c->controllerName()),
259 qPrintable(c->actionName()));
260 result.errorMessage = validationDataError(c, 0);
261 break;
262 }
263
264 if (valid) {
265 if (d->type != QMetaType::QString) {
266 const QVariant _v = d->valueToNumber(c, v, d->type);
267 if (_v.isValid()) {
268 result.value = _v;
269 } else {
270 result.errorMessage = parsingError(c);
271 }
272 } else {
273 result.value.setValue(v);
274 }
275 }
276 } else {
277 defaultValue(c, &result, "ValidatorBetween");
278 }
279
280 return result;
281}
282
284 const QVariant &errorData) const
285{
286 QString error;
287
288 Q_D(const ValidatorBetween);
289
290 const QVariantMap map = errorData.toMap();
291 QString min, max;
292 switch (d->type) {
293 case QMetaType::Char:
294 case QMetaType::Short:
295 case QMetaType::Int:
296 case QMetaType::Long:
299 min = c->locale().toString(map.value(QStringLiteral("min")).toLongLong());
300 max = c->locale().toString(map.value(QStringLiteral("max")).toLongLong());
301 break;
302 case QMetaType::UChar:
304 case QMetaType::UInt:
305 case QMetaType::ULong:
307 min = c->locale().toString(map.value(QStringLiteral("min")).toULongLong());
308 max = c->locale().toString(map.value(QStringLiteral("max")).toULongLong());
309 break;
310 case QMetaType::Float:
312 min = c->locale().toString(map.value(QStringLiteral("min")).toDouble());
313 max = c->locale().toString(map.value(QStringLiteral("max")).toDouble());
314 break;
315 default:
316 error = validationDataError(c);
317 return error;
318 }
319
320 const QString _label = label(c);
321
322 if (_label.isEmpty()) {
323 if (d->type == QMetaType::QString) {
324 error = c->translate("Cutelyst::ValidatorBetween",
325 "The text must be between %1 and %2 characters long.")
326 .arg(min, max);
327 } else {
328 error =
329 c->translate("Cutelyst::ValidatorBetween", "The value must be between %1 and %2.")
330 .arg(min, max);
331 }
332 } else {
333 if (d->type == QMetaType::QString) {
334 error = c->translate(
335 "Cutelyst::ValidatorBetween",
336 "The text in the “%1“ field must be between %2 and %3 characters long.")
337 .arg(_label, min, max);
338 } else {
339 error = c->translate("Cutelyst::ValidatorBetween",
340 "The value in the “%1” field must be between %2 and %3.")
341 .arg(_label, min, max);
342 }
343 }
344
345 return error;
346}
347
349{
350 QString error;
351
352 int field = errorData.toInt();
353 const QString _label = label(c);
354
355 if (field == -1) {
356 if (_label.isEmpty()) {
357 error = c->translate("Cutelyst::ValidatorBetween",
358 "The minimum comparison value is not valid.");
359 } else {
360 //: %1 will be replaced by the field label
361 error = c->translate("Cutelyst::ValidatorBetween",
362 "The minimum comparison value for the “%1” field is not valid.")
363 .arg(_label);
364 }
365 } else if (field == 0) {
366 Q_D(const ValidatorBetween);
367 if (_label.isEmpty()) {
368 error = c->translate("Cutelyst::ValidatorBetween",
369 "The comparison type with ID %1 is not supported.")
370 .arg(static_cast<int>(d->type));
371 } else {
372 //: %1 will be replaced by the type id, %2 will be replaced by the field label
373 error =
374 c->translate("Cutelyst::ValidatorBetween",
375 "The comparison type with ID %1 for the “%2” field is not supported.")
376 .arg(QString::number(static_cast<int>(d->type)), _label);
377 }
378 } else if (field == 1) {
379 if (_label.isEmpty()) {
380 error = c->translate("Cutelyst::ValidatorBetween",
381 "The maximum comparison value is not valid.");
382 } else {
383 //: %1 will be replaced by the field label
384 error = c->translate("Cutelyst::ValidatorBetween",
385 "The maximum comparison value for the “%1” field is not valid.")
386 .arg(_label);
387 }
388 }
389
390 return error;
391}
392
394{
395 QString error;
396 Q_UNUSED(errorData)
397 Q_D(const ValidatorBetween);
398
399 const QString _label = label(c);
400 if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
401 if (_label.isEmpty()) {
402 error = c->translate("Cutelyst::ValidatorBetween",
403 "Failed to parse the input value into a floating point number.");
404 } else {
405 //: %1 will be replaced by the field label
406 error = c->translate("Cutelyst::ValidatorBetween",
407 "Failed to parse the input value for the “%1” field into a "
408 "floating point number.")
409 .arg(_label);
410 }
411 } else {
412 if (_label.isEmpty()) {
413 error = c->translate("Cutelyst::ValidatorBetween",
414 "Failed to parse the input value into an integer number.");
415 } else {
416 //: %1 will be replaced by the field label
417 error =
418 c->translate(
419 "Cutelyst::ValidatorBetween",
420 "Failed to parse the input value for the “%1” field into an integer number.")
421 .arg(_label);
422 }
423 }
424
425 return error;
426}
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
ValidatorBetween(const QString &field, QMetaType::Type type, const QVariant &min, const QVariant &max, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new between validator.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
~ValidatorBetween() override
Deconstructs the between validator.
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
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 ...
ValidatorRule(const QString &field, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new ValidatorRule with the given parameters.
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
qlonglong toLongLong(const QString &s, bool *ok) const const
QString toString(qlonglong i) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool isEmpty() const const
int length() const const
QString number(int n, int base)
double toDouble(bool *ok) const const
qulonglong toULongLong(bool *ok, int base) const const
bool isValid() const const
void setValue(const T &value)
int toInt(bool *ok) const const
QMap< QString, QVariant > toMap() const const
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.