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