Cutelyst  2.13.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:
48  case QMetaType::LongLong:
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:
77  case QMetaType::ULongLong:
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<QString>(v);
164  }
165  }
166  } else {
167  defaultValue(c, &result, "ValidatorMax");
168  }
169 
170  return result;
171 }
172 
173 QString ValidatorMax::genericValidationError(Cutelyst::Context *c, const QVariant &errorData) const
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:
194  case QMetaType::ULongLong:
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 
225 QString ValidatorMax::genericValidationDataError(Context *c, const QVariant &errorData) const
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 
250 QString ValidatorMax::genericParsingError(Context *c, const QVariant &errorData) const
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 }
Cutelyst::ParamsMultiMap
QMap< QString, QString > ParamsMultiMap
Definition: paramsmultimap.h:36
Cutelyst::ValidatorMessages
Stores custom error messages and the input field label.
Definition: validatorrule.h:144
Cutelyst::ValidatorRule::value
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
Definition: validatorrule.cpp:41
Cutelyst::ValidatorRule::label
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
Definition: validatorrule.cpp:58
Cutelyst::ValidatorMax::genericValidationDataError
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
Definition: validatormax.cpp:225
Cutelyst::ValidatorRule::validationError
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
Definition: validatorrule.cpp:72
Cutelyst::Context
The Cutelyst Context.
Definition: context.h:50
Cutelyst::ValidatorRule
Base class for all validator rules.
Definition: validatorrule.h:292
Cutelyst::ValidatorRule::parsingError
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occured while parsing input.
Definition: validatorrule.cpp:102
Cutelyst::ValidatorRule::field
QString field() const
Returns the name of the field to validate.
Definition: validatorrule.cpp:39
Cutelyst::Context::translate
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:473
Cutelyst::ValidatorReturnType
Contains the result of a single input parameter validation.
Definition: validatorrule.h:62
Cutelyst::ValidatorMax::~ValidatorMax
~ValidatorMax() override
Deconstructs the max validator.
Definition: validatormax.cpp:28
Cutelyst::Context::locale
QLocale locale() const
Definition: context.cpp:449
Cutelyst::ValidatorMax::genericValidationError
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message.
Definition: validatormax.cpp:173
Cutelyst::ValidatorMax::validate
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
Definition: validatormax.cpp:32
Cutelyst
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
Cutelyst::ValidatorMax::ValidatorMax
ValidatorMax(const QString &field, QMetaType::Type type, const QVariant &max, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new max validator.
Definition: validatormax.cpp:23
Cutelyst::ValidatorReturnType::value
QVariant value
Definition: validatorrule.h:64
Cutelyst::ValidatorReturnType::errorMessage
QString errorMessage
Definition: validatorrule.h:63
Cutelyst::ValidatorMax
Checks if a value is not bigger or longer than a maximum value.
Definition: validatormax.h:53
Cutelyst::ValidatorRule::validationDataError
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
Definition: validatorrule.cpp:132
Cutelyst::ValidatorMax::genericParsingError
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
Definition: validatormax.cpp:250
Cutelyst::ValidatorRule::defaultValue
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 ...
Definition: validatorrule.cpp:162