Cutelyst  3.7.0
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:
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:
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 
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:
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 
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 
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
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