cutelyst  3.9.0
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 }
The Cutelyst Context.
Definition: context.h:39
QLocale locale() const noexcept
Definition: context.cpp:460
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:484
Checks if a value is not bigger or longer than a maximum value.
Definition: validatormax.h:46
~ValidatorMax() override
Deconstructs the max validator.
ValidatorMax(const QString &field, QMetaType::Type type, const QVariant &max, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new max validator.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
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.
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
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
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.
Definition: validatorrule.h:49