cutelyst  3.9.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatormax.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2022 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatormax_p.h"
7 
8 using namespace Cutelyst;
9 
11  QMetaType::Type type,
12  const QVariant &max,
13  const Cutelyst::ValidatorMessages &messages,
14  const QString &defValKey)
15  : ValidatorRule(*new ValidatorMaxPrivate(field, type, max, messages, defValKey))
16 {
17 }
18 
20 {
21 }
22 
24 {
25  ValidatorReturnType result;
26 
27  const QString v = value(params);
28 
29  if (!v.isEmpty()) {
30  Q_D(const ValidatorMax);
31  bool ok = false;
32  bool valid = false;
33 
34  switch (d->type) {
35  case QMetaType::Char:
36  case QMetaType::Short:
37  case QMetaType::Int:
38  case QMetaType::Long:
40  {
41  const qlonglong val = c->locale().toLongLong(v, &ok);
42  if (Q_UNLIKELY(!ok)) {
43  result.errorMessage = parsingError(c);
44  qCWarning(C_VALIDATOR,
45  "ValidatorMax: Failed to parse value of field %s into number at %s::%s.",
46  qPrintable(field()),
47  qPrintable(c->controllerName()),
48  qPrintable(c->actionName()));
49  } else {
50  const qlonglong max = d->extractLongLong(c, params, d->max, &ok);
51  if (Q_UNLIKELY(!ok)) {
52  result.errorMessage = validationDataError(c, 1);
53  qCWarning(
54  C_VALIDATOR,
55  "ValidatorMax: Invalid maximum comparison value for field %s in %s::%s.",
56  qPrintable(field()),
57  qPrintable(c->controllerName()),
58  qPrintable(c->actionName()));
59  } else {
60  if (val > max) {
61  result.errorMessage =
63  QVariantMap{{QStringLiteral("val"), val},
64  {QStringLiteral("max"), max}});
65  qCDebug(C_VALIDATOR,
66  "ValidatorMax: Validation failed for field %s in %s::%s: %lli is "
67  "not smaller than %lli.",
68  qPrintable(field()),
69  qPrintable(c->controllerName()),
70  qPrintable(c->actionName()),
71  val,
72  max);
73  } else {
74  valid = true;
75  }
76  }
77  }
78  } break;
79  case QMetaType::UChar:
80  case QMetaType::UShort:
81  case QMetaType::UInt:
82  case QMetaType::ULong:
84  {
85  const qulonglong val = v.toULongLong(&ok);
86  if (Q_UNLIKELY(!ok)) {
87  result.errorMessage = parsingError(c);
88  qCWarning(C_VALIDATOR,
89  "ValidatorMax: Failed to parse value of field %s into number at %s::%s.",
90  qPrintable(field()),
91  qPrintable(c->controllerName()),
92  qPrintable(c->actionName()));
93  } else {
94  const qulonglong max = d->extractULongLong(c, params, d->max, &ok);
95  if (Q_UNLIKELY(!ok)) {
96  result.errorMessage = validationDataError(c, 1);
97  qCWarning(
98  C_VALIDATOR,
99  "ValidatorMax: Invalid maximum comparison value for field %s in %s::%s.",
100  qPrintable(field()),
101  qPrintable(c->controllerName()),
102  qPrintable(c->actionName()));
103  } else {
104  if (val > max) {
105  result.errorMessage =
106  validationError(c,
107  QVariantMap{{QStringLiteral("val"), val},
108  {QStringLiteral("max"), max}});
109  qCDebug(C_VALIDATOR,
110  "ValidatorMax: Validation failed for field %s in %s::%s: %llu is "
111  "not smaller than %llu.",
112  qPrintable(field()),
113  qPrintable(c->controllerName()),
114  qPrintable(c->actionName()),
115  val,
116  max);
117  } else {
118  valid = true;
119  }
120  }
121  }
122  } break;
123  case QMetaType::Float:
124  case QMetaType::Double:
125  {
126  const double val = v.toDouble(&ok);
127  if (Q_UNLIKELY(!ok)) {
128  result.errorMessage = parsingError(c);
129  qCWarning(C_VALIDATOR,
130  "ValidatorMax: Failed to parse value of field %s into number at %s::%s.",
131  qPrintable(field()),
132  qPrintable(c->controllerName()),
133  qPrintable(c->actionName()));
134  } else {
135  const double max = d->extractDouble(c, params, d->max, &ok);
136  if (Q_UNLIKELY(!ok)) {
137  result.errorMessage = validationDataError(c, 1);
138  qCWarning(
139  C_VALIDATOR,
140  "ValidatorMax: Invalid maximum comparison value for field %s in %s::%s.",
141  qPrintable(field()),
142  qPrintable(c->controllerName()),
143  qPrintable(c->actionName()));
144  } else {
145  if (val > max) {
146  result.errorMessage =
147  validationError(c,
148  QVariantMap{{QStringLiteral("val"), val},
149  {QStringLiteral("max"), max}});
150  qCDebug(C_VALIDATOR,
151  "ValidatorMax: Validation failed for field %s in %s::%s: %f is not "
152  "smaller than %f.",
153  qPrintable(field()),
154  qPrintable(c->controllerName()),
155  qPrintable(c->actionName()),
156  val,
157  max);
158  } else {
159  valid = true;
160  }
161  }
162  }
163  } break;
164  case QMetaType::QString:
165  {
166  const qlonglong val = static_cast<qlonglong>(v.length());
167  const qlonglong max = d->extractLongLong(c, params, d->max, &ok);
168  if (Q_UNLIKELY(!ok)) {
169  result.errorMessage = validationDataError(c, 1);
170  qCWarning(C_VALIDATOR,
171  "ValidatorMax: Invalid maximum comparison value for field %s in %s::%s.",
172  qPrintable(field()),
173  qPrintable(c->controllerName()),
174  qPrintable(c->actionName()));
175  } else {
176  if (val > max) {
177  result.errorMessage = validationError(
178  c, QVariantMap{{QStringLiteral("val"), val}, {QStringLiteral("max"), max}});
179  qCDebug(C_VALIDATOR,
180  "ValidatorMax: Validation failed for field %s in %s::%s: string length "
181  "%lli is not smaller than %lli.",
182  qPrintable(field()),
183  qPrintable(c->controllerName()),
184  qPrintable(c->actionName()),
185  val,
186  max);
187  } else {
188  valid = true;
189  }
190  }
191  } break;
192  default:
193  qCWarning(C_VALIDATOR,
194  "ValidatorMax: The comparison type with ID %i for field %s at %s::%s is not "
195  "supported.",
196  static_cast<int>(d->type),
197  qPrintable(field()),
198  qPrintable(c->controllerName()),
199  qPrintable(c->actionName()));
200  result.errorMessage = validationDataError(c, 0);
201  break;
202  }
203 
204  if (valid) {
205  if (d->type != QMetaType::QString) {
206  const QVariant _v = d->valueToNumber(c, v, d->type);
207  if (_v.isValid()) {
208  result.value = _v;
209  } else {
210  result.errorMessage = parsingError(c);
211  }
212  } else {
213  result.value.setValue(v);
214  }
215  }
216  } else {
217  defaultValue(c, &result, "ValidatorMax");
218  }
219 
220  return result;
221 }
222 
224 {
225  QString error;
226 
227  Q_D(const ValidatorMax);
228 
229  const QVariantMap map = errorData.toMap();
230  QString max;
231  switch (d->type) {
232  case QMetaType::Char:
233  case QMetaType::Short:
234  case QMetaType::Int:
235  case QMetaType::Long:
236  case QMetaType::LongLong:
237  case QMetaType::QString:
238  max = c->locale().toString(map.value(QStringLiteral("max")).toLongLong());
239  break;
240  case QMetaType::UChar:
241  case QMetaType::UShort:
242  case QMetaType::UInt:
243  case QMetaType::ULong:
245  max = c->locale().toString(map.value(QStringLiteral("max")).toULongLong());
246  break;
247  case QMetaType::Float:
248  case QMetaType::Double:
249  max = c->locale().toString(map.value(QStringLiteral("max")).toDouble());
250  break;
251  default:
252  error = validationDataError(c);
253  return error;
254  }
255 
256  const QString _label = label(c);
257 
258  if (_label.isEmpty()) {
259  if (d->type == QMetaType::QString) {
260  error = c->translate("Cutelyst::ValidatorMax",
261  "The text must be shorter than %1 characters.")
262  .arg(max);
263  } else {
264  error =
265  c->translate("Cutelyst::ValidatorMax", "The value must be lower than %1.").arg(max);
266  }
267  } else {
268  if (d->type == QMetaType::QString) {
269  error = c->translate("Cutelyst::ValidatorMax",
270  "The text in the “%1“ field must be shorter than %2 characters.")
271  .arg(_label, max);
272  } else {
273  error = c->translate("Cutelyst::ValidatorMax",
274  "The value in the “%1” field must be lower than %2.")
275  .arg(_label, max);
276  }
277  }
278 
279  return error;
280 }
281 
283 {
284  QString error;
285 
286  int field = errorData.toInt();
287  const QString _label = label(c);
288 
289  if (field == 0) {
290  Q_D(const ValidatorMax);
291  if (_label.isEmpty()) {
292  error = c->translate("Cutelyst::ValidatorMax",
293  "The comparison type with ID %1 is not supported.")
294  .arg(static_cast<int>(d->type));
295  } else {
296  error =
297  c->translate("Cutelyst::ValidatorMax",
298  "The comparison type with ID %1 for the “%2” field is not supported.")
299  .arg(QString::number(static_cast<int>(d->type)), _label);
300  }
301  } else if (field == 1) {
302  if (_label.isEmpty()) {
303  error = c->translate("Cutelyst::ValidatorMax",
304  "The maximum comparison value is not valid.");
305  } else {
306  error = c->translate("Cutelyst::ValidatorMax",
307  "The maximum comparison value for the “%1” field is not valid.")
308  .arg(_label);
309  }
310  }
311 
312  return error;
313 }
314 
316 {
317  QString error;
318  Q_UNUSED(errorData)
319  Q_D(const ValidatorMax);
320 
321  const QString _label = label(c);
322  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
323  if (_label.isEmpty()) {
324  error = c->translate("Cutelyst::ValidatorMax",
325  "Failed to parse the input value into a floating point number.");
326  } else {
327  error = c->translate("Cutelyst::ValidatorMax",
328  "Failed to parse the input value for the “%1” field into a "
329  "floating point number.")
330  .arg(_label);
331  }
332  } else {
333  if (_label.isEmpty()) {
334  error = c->translate("Cutelyst::ValidatorMax",
335  "Failed to parse the input value into an integer number.");
336  } else {
337  error =
338  c->translate(
339  "Cutelyst::ValidatorMax",
340  "Failed to parse the input value for the “%1” field into an integer number.")
341  .arg(_label);
342  }
343  }
344 
345  return error;
346 }
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.
qlonglong toLongLong(QStringView s, bool *ok) const const
Stores custom error messages and the input field label.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
double toDouble(bool *ok) const const
QString toString(QDate date, FormatType format) const const
The Cutelyst Context.
Definition: context.h:38
QString number(double n, char format, int precision)
int toInt(bool *ok) const const
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
bool isEmpty() const const
ValidatorMax(const QString &field, QMetaType::Type type, const QVariant &max, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new max validator.
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:490
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.
qulonglong toULongLong(bool *ok, int base) const const
QLocale locale() const noexcept
Definition: context.cpp:466
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
QMap< QString, QVariant > toMap() const const
~ValidatorMax() override
Deconstructs the max validator.
qsizetype length() const const
QString field() const
Returns the name of the field to validate.
bool isValid() const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
Checks if a value is not bigger or longer than a maximum value.
Definition: validatormax.h:45
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message.
QString arg(Args &&... args) 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 ...
void setValue(QVariant &&value)