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