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