cutelyst  3.7.0
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 
10 ValidatorMin::ValidatorMin(const QString &field, QMetaType::Type type, const QVariant &min, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
11  ValidatorRule(*new ValidatorMinPrivate(field, type, min, messages, defValKey))
12 {
13 }
14 
16 {
17 }
18 
20 {
21  ValidatorReturnType result;
22 
23  const QString v = value(params);
24 
25  Q_D(const ValidatorMin);
26 
27  if (!v.isEmpty()) {
28  bool ok = false;
29  bool valid = false;
30 
31  switch (d->type) {
32  case QMetaType::Char:
33  case QMetaType::Short:
34  case QMetaType::Int:
35  case QMetaType::Long:
36  case QMetaType::LongLong:
37  {
38  const qlonglong val = c->locale().toLongLong(v, &ok);
39  if (Q_UNLIKELY(!ok)) {
40  result.errorMessage = parsingError(c);
41  qCWarning(C_VALIDATOR, "ValidatorMin: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
42  } else {
43  const qlonglong min = d->extractLongLong(c, params, d->min, &ok);
44  if (Q_UNLIKELY(!ok)) {
45  result.errorMessage = validationDataError(c, -1);
46  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
47  } else {
48  if (val < min) {
49  result.errorMessage = validationError(c, QVariantMap{
50  {QStringLiteral("val"), val},
51  {QStringLiteral("min"), min}
52  });
53  qCDebug(C_VALIDATOR, "ValidatorMin: Validation failed for field %s in %s::%s: %lli is not greater than %lli.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), val, min);
54  } else {
55  valid = true;
56  }
57  }
58  }
59  }
60  break;
61  case QMetaType::UChar:
62  case QMetaType::UShort:
63  case QMetaType::UInt:
64  case QMetaType::ULong:
65  case QMetaType::ULongLong:
66  {
67  const qulonglong val = v.toULongLong(&ok);
68  if (Q_UNLIKELY(!ok)) {
69  result.errorMessage = parsingError(c);
70  qCWarning(C_VALIDATOR, "ValidatorMin: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
71  } else {
72  const qulonglong min = d->extractULongLong(c, params, d->min, &ok);
73  if (Q_UNLIKELY(!ok)) {
74  result.errorMessage = validationDataError(c, -1);
75  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
76  } else {
77  if (val < min) {
78  result.errorMessage = validationError(c, QVariantMap{
79  {QStringLiteral("val"), val},
80  {QStringLiteral("min"), min}
81  });
82  qCDebug(C_VALIDATOR, "ValidatorMin: Validation failed for field %s in %s::%s: %llu is not greater than %llu.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), val, min);
83  } else {
84  valid = true;
85  }
86  }
87  }
88  }
89  break;
90  case QMetaType::Float:
91  case QMetaType::Double:
92  {
93  const double val = v.toDouble(&ok);
94  if (Q_UNLIKELY(!ok)) {
95  result.errorMessage = parsingError(c);
96  qCWarning(C_VALIDATOR, "ValidatorMin: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
97  } else {
98  const double min = d->extractDouble(c, params, d->min, &ok);
99  if (Q_UNLIKELY(!ok)) {
100  result.errorMessage = validationDataError(c, -1);
101  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
102  } else {
103  if (val < min) {
104  result.errorMessage = validationError(c, QVariantMap{
105  {QStringLiteral("val"), val},
106  {QStringLiteral("min"), min}
107  });
108  qCDebug(C_VALIDATOR, "ValidatorMin: Validation failed for field %s in %s::%s: %f is not greater than %f.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), val, min);
109  } else {
110  valid = true;
111  }
112  }
113  }
114  }
115  break;
116  case QMetaType::QString:
117  {
118  const qlonglong val = static_cast<qlonglong>(v.length());
119  const qlonglong min = d->extractLongLong(c, params, d->min, &ok);
120  if (Q_UNLIKELY(!ok)) {
121  result.errorMessage = validationDataError(c, -1);
122  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
123  } else {
124  if (val < min) {
125  result.errorMessage = validationError(c, QVariantMap{
126  {QStringLiteral("val"), val},
127  {QStringLiteral("min"), min}
128  });
129  qCDebug(C_VALIDATOR, "ValidatorMin: Validation failed for field %s in %s::%s: string length %lli is not longer than %lli.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), val, min);
130  } else {
131  valid = true;
132  }
133  }
134  }
135  break;
136  default:
137  qCWarning(C_VALIDATOR, "ValidatorMin: The comparison type with ID %i for field %s at %s::%s is not supported.", static_cast<int>(d->type), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
138  result.errorMessage = validationDataError(c, 0);
139  break;
140  }
141 
142  if (valid) {
143  if (d->type != QMetaType::QString) {
144  const QVariant _v = d->valueToNumber(c, v, d->type);
145  if (_v.isValid()) {
146  result.value = _v;
147  } else {
148  result.errorMessage = parsingError(c);
149  }
150  } else {
151  result.value.setValue(v);
152  }
153  }
154  } else {
155  defaultValue(c, &result, "ValidatorMin");
156  }
157 
158  return result;
159 }
160 
161 QString ValidatorMin::genericValidationError(Cutelyst::Context *c, const QVariant &errorData) const
162 {
163  QString error;
164 
165  Q_D(const ValidatorMin);
166 
167  const QVariantMap map = errorData.toMap();
168  QString min;
169  switch (d->type) {
170  case QMetaType::Char:
171  case QMetaType::Short:
172  case QMetaType::Int:
173  case QMetaType::Long:
174  case QMetaType::LongLong:
175  case QMetaType::QString:
176  min = c->locale().toString(map.value(QStringLiteral("min")).toLongLong());
177  break;
178  case QMetaType::UChar:
179  case QMetaType::UShort:
180  case QMetaType::UInt:
181  case QMetaType::ULong:
182  case QMetaType::ULongLong:
183  min = c->locale().toString(map.value(QStringLiteral("min")).toULongLong());
184  break;
185  case QMetaType::Float:
186  case QMetaType::Double:
187  min = c->locale().toString(map.value(QStringLiteral("min")).toDouble());
188  break;
189  default:
190  error = validationDataError(c);
191  return error;
192  }
193 
194  const QString _label = label(c);
195 
196  if (_label.isEmpty()) {
197  if (d->type == QMetaType::QString) {
198  error = c->translate("Cutelyst::ValidatorMin", "The text must be longer than %1 characters.").arg(min);
199  } else {
200  error = c->translate("Cutelyst::ValidatorMin", "The value must be greater than %1.").arg(min);
201  }
202  } else {
203  if (d->type == QMetaType::QString) {
204  error = c->translate("Cutelyst::ValidatorMin", "The text in the “%1“ field must be longer than %2 characters.").arg(_label, min);
205  } else {
206  error = c->translate("Cutelyst::ValidatorMin", "The value in the “%1” field must be greater than %2.").arg(_label, min);
207  }
208  }
209 
210  return error;
211 }
212 
213 QString ValidatorMin::genericValidationDataError(Context *c, const QVariant &errorData) const
214 {
215  QString error;
216 
217  int field = errorData.toInt();
218  const QString _label = label(c);
219 
220  if (field == -1) {
221  if (_label.isEmpty()) {
222  error = c->translate("Cutelyst::ValidatorMin", "The minimum comparison value is not valid.");
223  } else {
224  error = c->translate("Cutelyst::ValidatorMin", "The minimum comparison value for the “%1” field is not valid.").arg(_label);
225  }
226  } else if (field == 0) {
227  Q_D(const ValidatorMin);
228  if (_label.isEmpty()) {
229  error = c->translate("Cutelyst::ValidatorMin", "The comparison type with ID %1 is not supported.").arg(static_cast<int>(d->type));
230  } else {
231  error = c->translate("Cutelyst::ValidatorMin", "The comparison type with ID %1 for the “%2” field is not supported.").arg(QString::number(static_cast<int>(d->type)), _label);
232  }
233  }
234 
235  return error;
236 }
237 
238 QString ValidatorMin::genericParsingError(Context *c, const QVariant &errorData) const
239 {
240  QString error;
241  Q_UNUSED(errorData)
242  Q_D(const ValidatorMin);
243 
244  const QString _label = label(c);
245  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
246  if (_label.isEmpty()) {
247  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value into a floating point number.");
248  } else {
249  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value for the “%1” field into a floating point number.").arg(_label);
250  }
251  } else {
252  if (_label.isEmpty()) {
253  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value into an integer number.");
254  } else {
255  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value for the “%1” field into an integer number.").arg(_label);
256  }
257  }
258 
259  return error;
260 }
The Cutelyst Context.
Definition: context.h:39
QLocale locale() const noexcept
Definition: context.cpp:453
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:477
Checks if a value is not smaller or shorter than a maximum value.
Definition: validatormin.h:41
~ValidatorMin() override
Deconstructs the min 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.
ValidatorMin(const QString &field, QMetaType::Type type, const QVariant &min, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new min validator.
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 occured 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.
Definition: validatorrule.h:49