Cutelyst  2.5.0
validatormin.cpp
1 /*
2  * Copyright (C) 2017-2018 Matthias Fehring <kontakt@buschmann23.de>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "validatormin_p.h"
20 
21 using namespace Cutelyst;
22 
23 ValidatorMin::ValidatorMin(const QString &field, QMetaType::Type type, const QVariant &min, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
24  ValidatorRule(*new ValidatorMinPrivate(field, type, min, messages, defValKey))
25 {
26 }
27 
29 {
30 }
31 
33 {
34  ValidatorReturnType result;
35 
36  const QString v = value(params);
37 
38  Q_D(const ValidatorMin);
39 
40  if (!v.isEmpty()) {
41  bool ok = false;
42  bool valid = false;
43 
44  switch (d->type) {
45  case QMetaType::Char:
46  case QMetaType::Short:
47  case QMetaType::Int:
48  case QMetaType::Long:
49  case QMetaType::LongLong:
50  {
51  const qlonglong val = c->locale().toLongLong(v, &ok);
52  if (Q_UNLIKELY(!ok)) {
53  result.errorMessage = parsingError(c);
54  qCWarning(C_VALIDATOR, "ValidatorMin: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
55  } else {
56  const qlonglong min = d->extractLongLong(c, params, d->min, &ok);
57  if (Q_UNLIKELY(!ok)) {
58  result.errorMessage = validationDataError(c, -1);
59  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
60  } else {
61  if (val < min) {
62  result.errorMessage = validationError(c, QVariantMap{
63  {QStringLiteral("val"), val},
64  {QStringLiteral("min"), min}
65  });
66  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);
67  } else {
68  valid = true;
69  }
70  }
71  }
72  }
73  break;
74  case QMetaType::UChar:
75  case QMetaType::UShort:
76  case QMetaType::UInt:
77  case QMetaType::ULong:
78  case QMetaType::ULongLong:
79  {
80  const qulonglong val = v.toULongLong(&ok);
81  if (Q_UNLIKELY(!ok)) {
82  result.errorMessage = parsingError(c);
83  qCWarning(C_VALIDATOR, "ValidatorMin: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
84  } else {
85  const qulonglong min = d->extractULongLong(c, params, d->min, &ok);
86  if (Q_UNLIKELY(!ok)) {
87  result.errorMessage = validationDataError(c, -1);
88  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
89  } else {
90  if (val < min) {
91  result.errorMessage = validationError(c, QVariantMap{
92  {QStringLiteral("val"), val},
93  {QStringLiteral("min"), min}
94  });
95  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);
96  } else {
97  valid = true;
98  }
99  }
100  }
101  }
102  break;
103  case QMetaType::Float:
104  case QMetaType::Double:
105  {
106  const double val = v.toDouble(&ok);
107  if (Q_UNLIKELY(!ok)) {
108  result.errorMessage = parsingError(c);
109  qCWarning(C_VALIDATOR, "ValidatorMin: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
110  } else {
111  const double min = d->extractDouble(c, params, d->min, &ok);
112  if (Q_UNLIKELY(!ok)) {
113  result.errorMessage = validationDataError(c, -1);
114  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
115  } else {
116  if (val < min) {
117  result.errorMessage = validationError(c, QVariantMap{
118  {QStringLiteral("val"), val},
119  {QStringLiteral("min"), min}
120  });
121  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);
122  } else {
123  valid = true;
124  }
125  }
126  }
127  }
128  break;
129  case QMetaType::QString:
130  {
131  const qlonglong val = static_cast<qlonglong>(v.length());
132  const qlonglong min = d->extractLongLong(c, params, d->min, &ok);
133  if (Q_UNLIKELY(!ok)) {
134  result.errorMessage = validationDataError(c, -1);
135  qCWarning(C_VALIDATOR, "ValidatorMin: Invalid minimum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
136  } else {
137  if (val < min) {
138  result.errorMessage = validationError(c, QVariantMap{
139  {QStringLiteral("val"), val},
140  {QStringLiteral("min"), min}
141  });
142  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);
143  } else {
144  valid = true;
145  }
146  }
147  }
148  break;
149  default:
150  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()));
151  result.errorMessage = validationDataError(c, 0);
152  break;
153  }
154 
155  if (valid) {
156  if (d->type != QMetaType::QString) {
157  const QVariant _v = d->valueToNumber(c, v, d->type);
158  if (_v.isValid()) {
159  result.value = _v;
160  } else {
161  result.errorMessage = parsingError(c);
162  }
163  } else {
164  result.value.setValue<QString>(v);
165  }
166  }
167  } else {
168  defaultValue(c, &result, "ValidatorMin");
169  }
170 
171  return result;
172 }
173 
174 QString ValidatorMin::genericValidationError(Cutelyst::Context *c, const QVariant &errorData) const
175 {
176  QString error;
177 
178  Q_D(const ValidatorMin);
179 
180  const QVariantMap map = errorData.toMap();
181  QString min;
182  switch (d->type) {
183  case QMetaType::Char:
184  case QMetaType::Short:
185  case QMetaType::Int:
186  case QMetaType::Long:
187  case QMetaType::LongLong:
188  case QMetaType::QString:
189  min = c->locale().toString(map.value(QStringLiteral("min")).toLongLong());
190  break;
191  case QMetaType::UChar:
192  case QMetaType::UShort:
193  case QMetaType::UInt:
194  case QMetaType::ULong:
195  case QMetaType::ULongLong:
196  min = c->locale().toString(map.value(QStringLiteral("min")).toULongLong());
197  break;
198  case QMetaType::Float:
199  case QMetaType::Double:
200  min = c->locale().toString(map.value(QStringLiteral("min")).toDouble());
201  break;
202  default:
203  error = validationDataError(c);
204  return error;
205  }
206 
207  const QString _label = label(c);
208 
209  if (_label.isEmpty()) {
210  if (d->type == QMetaType::QString) {
211  error = c->translate("Cutelyst::ValidatorMin", "The text must be longer than %1 characters.").arg(min);
212  } else {
213  error = c->translate("Cutelyst::ValidatorMin", "The value must be greater than %1.").arg(min);
214  }
215  } else {
216  if (d->type == QMetaType::QString) {
217  error = c->translate("Cutelyst::ValidatorMin", "The text in the “%1“ field must be longer than %2 characters.").arg(_label, min);
218  } else {
219  error = c->translate("Cutelyst::ValidatorMin", "The value in the “%1” field must be greater than %2.").arg(_label, min);
220  }
221  }
222 
223  return error;
224 }
225 
226 QString ValidatorMin::genericValidationDataError(Context *c, const QVariant &errorData) const
227 {
228  QString error;
229 
230  int field = errorData.toInt();
231  const QString _label = label(c);
232 
233  if (field == -1) {
234  if (_label.isEmpty()) {
235  error = c->translate("Cutelyst::ValidatorMin", "The minimum comparison value is not valid.");
236  } else {
237  error = c->translate("Cutelyst::ValidatorMin", "The minimum comparison value for the “%1” field is not valid.").arg(_label);
238  }
239  } else if (field == 0) {
240  Q_D(const ValidatorMin);
241  if (_label.isEmpty()) {
242  error = c->translate("Cutelyst::ValidatorMin", "The comparison type with ID %1 is not supported.").arg(static_cast<int>(d->type));
243  } else {
244  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);
245  }
246  }
247 
248  return error;
249 }
250 
251 QString ValidatorMin::genericParsingError(Context *c, const QVariant &errorData) const
252 {
253  QString error;
254  Q_UNUSED(errorData)
255  Q_D(const ValidatorMin);
256 
257  const QString _label = label(c);
258  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
259  if (_label.isEmpty()) {
260  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value into a floating point number.");
261  } else {
262  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value for the “%1” field into a floating point number.").arg(_label);
263  }
264  } else {
265  if (_label.isEmpty()) {
266  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value into an integer number.");
267  } else {
268  error = c->translate("Cutelyst::ValidatorMin", "Failed to parse the input value for the “%1” field into an integer number.").arg(_label);
269  }
270  }
271 
272  return error;
273 }
QMap< QString, QString > ParamsMultiMap
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 occured while parsing input.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
ValidatorMin(const QString &field, QMetaType::Type type, const QVariant &min, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new min validator.
Stores custom error messages and the input field label.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
QLocale locale() const
Definition: context.cpp:390
The Cutelyst Context.
Definition: context.h:50
~ValidatorMin()
Deconstructs the min validator.
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:414
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.
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.
Checks if a value is not smaller or shorter than a maximum value.
Definition: validatormin.h:53
QString field() const
Returns the name of the field to validate.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:62
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 ...