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