Cutelyst  3.1.0
validatorsize.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 "validatorsize_p.h"
20 
21 using namespace Cutelyst;
22 
23 ValidatorSize::ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
24  ValidatorRule(*new ValidatorSizePrivate(field, type, size, 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 
40  Q_D(const ValidatorSize);
41  bool ok = false;
42  bool valid = false;
43 
44  switch (d->type) {
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, "ValidatorSize: 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 size = d->extractLongLong(c, params, d->size, &ok);
56  if (Q_UNLIKELY(!ok)) {
57  result.errorMessage = validationDataError(c, 1);
58  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid comparison size for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
59  } else {
60  if (val != size) {
61  result.errorMessage = validationError(c, QVariantMap{
62  {QStringLiteral("val"), val},
63  {QStringLiteral("size"), size}
64  });
65  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: value is not %lli.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
66  } else {
67  valid = true;
68  }
69  }
70  }
71  }
72  break;
73  case QMetaType::UShort:
74  case QMetaType::UInt:
75  case QMetaType::ULong:
77  {
78  const qulonglong val = v.toULongLong(&ok);
79  if (Q_UNLIKELY(!ok)) {
80  result.errorMessage = parsingError(c);
81  qCWarning(C_VALIDATOR, "ValidatorSize: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
82  } else {
83  const qulonglong size = d->extractULongLong(c, params, d->size, &ok);
84  if (Q_UNLIKELY(!ok)) {
85  result.errorMessage = validationDataError(c, 1);
86  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
87  } else {
88  if (val != size) {
89  result.errorMessage = validationError(c, QVariantMap{
90  {QStringLiteral("val"), val},
91  {QStringLiteral("size"), size}
92  });
93  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: value is not %llu.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
94  } else {
95  valid = true;
96  }
97  }
98  }
99  }
100  break;
101  case QMetaType::Float:
102  case QMetaType::Double:
103  {
104  const double val = v.toDouble(&ok);
105  if (Q_UNLIKELY(!ok)) {
106  result.errorMessage = parsingError(c);
107  qCWarning(C_VALIDATOR, "ValidatorSize: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
108  } else {
109  const double size = d->extractDouble(c, params, d->size, &ok);
110  if (Q_UNLIKELY(!ok)) {
111  result.errorMessage = validationDataError(c, 1);
112  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
113  } else {
114  if (val != size) {
115  result.errorMessage = validationError(c, QVariantMap{
116  {QStringLiteral("val"), val},
117  {QStringLiteral("size"), size}
118  });
119  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: value is not %f.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
120  } else {
121  valid = true;
122  }
123  }
124  }
125  }
126  break;
127  case QMetaType::QString:
128  {
129  const qlonglong val = static_cast<qlonglong>(v.length());
130  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
131  if (Q_UNLIKELY(!ok)) {
132  result.errorMessage = validationDataError(c, 1);
133  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
134  } else {
135  if (val != size) {
136  result.errorMessage = validationError(c, QVariantMap{
137  {QStringLiteral("val"), val},
138  {QStringLiteral("size"), size}
139  });
140  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: string length is not %lli.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
141  } else {
142  valid = true;
143  }
144  }
145  }
146  break;
147  default:
148  qCWarning(C_VALIDATOR, "ValidatorSize: 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()));
149  result.errorMessage = validationDataError(c, 0);
150  break;
151  }
152 
153  if (valid) {
154  if (d->type != QMetaType::QString) {
155  const QVariant _v = d->valueToNumber(c, v, d->type);
156  if (_v.isValid()) {
157  result.value = _v;
158  } else {
159  result.errorMessage = parsingError(c);
160  }
161  } else {
162  result.value.setValue(v);
163  }
164  }
165  } else {
166  defaultValue(c, &result, "ValidatorSize");
167  }
168 
169  return result;
170 }
171 
173 {
174  QString error;
175 
176  Q_D(const ValidatorSize);
177 
178  const QVariantMap map = errorData.toMap();
179  QString size;
180  switch (d->type) {
181  case QMetaType::Short:
182  case QMetaType::Int:
183  case QMetaType::Long:
184  case QMetaType::LongLong:
185  case QMetaType::QString:
186  size = c->locale().toString(map.value(QStringLiteral("size")).toLongLong());
187  break;
188  case QMetaType::UShort:
189  case QMetaType::UInt:
190  case QMetaType::ULong:
192  size = c->locale().toString(map.value(QStringLiteral("size")).toULongLong());
193  break;
194  case QMetaType::Float:
195  case QMetaType::Double:
196  size = c->locale().toString(map.value(QStringLiteral("size")).toDouble());
197  break;
198  default:
199  error = validationDataError(c);
200  return error;
201  }
202 
203  const QString _label = label(c);
204 
205  if (_label.isEmpty()) {
206  if (d->type == QMetaType::QString) {
207  //: %1 will be replaced by the required string size
208  error = c->translate("Cutelyst::ValidatorSize", "The text must be exactly %1 characters long.").arg(size);
209  } else {
210  //: %1 will be replaced by the required size/value
211  error = c->translate("Cutelyst::ValidatorSize", "The value must be %1.").arg(size);
212  }
213  } else {
214  if (d->type == QMetaType::QString) {
215  //: %1 will be replaced by the field label, %2 will be replaced by the required string size
216  error = c->translate("Cutelyst::ValidatorSize", "The text in the “%1“ field must be exactly %2 characters long.").arg(_label, size);
217  } else {
218  //: %1 will be replaced by the field label, %2 will be replaced by the required size/value
219  error = c->translate("Cutelyst::ValidatorSize", "The value in the “%1” field must be %2.").arg(_label, size);
220  }
221  }
222 
223  return error;
224 }
225 
227 {
228  QString error;
229 
230  int field = errorData.toInt();
231  const QString _label = label(c);
232 
233  if (field == 0) {
234  Q_D(const ValidatorSize);
235  if (_label.isEmpty()) {
236  error = c->translate("Cutelyst::ValidatorSize", "The comparison type with ID %1 is not supported.").arg(static_cast<int>(d->type));
237  } else {
238  error = c->translate("Cutelyst::ValidatorSize", "The comparison type with ID %1 for the “%2” field is not supported.").arg(QString::number(static_cast<int>(d->type)), _label);
239  }
240  } else if (field == 1) {
241  if (_label.isEmpty()) {
242  error = c->translate("Cutelyst::ValidatorSize", "The comparison value is not valid.");
243  } else {
244  //: %1 will be replaced by the field label
245  error = c->translate("Cutelyst::ValidatorSize", "The comparison value for the “%1” field is not valid.").arg(_label);
246  }
247  }
248 
249  return error;
250 }
251 
253 {
254  QString error;
255  Q_UNUSED(errorData)
256  Q_D(const ValidatorSize);
257 
258  const QString _label = label(c);
259  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
260  if (_label.isEmpty()) {
261  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value into a floating point number.");
262  } else {
263  //: %1 will be replaced by the field label
264  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value for the “%1” field into a floating point number.").arg(_label);
265  }
266  } else {
267  if (_label.isEmpty()) {
268  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value into an integer number.");
269  } else {
270  //: %1 will be replaced by the field label
271  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value for the “%1” field into an integer number.").arg(_label);
272  }
273  }
274 
275  return error;
276 }
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
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 field under validation must have a size matching the given value.
Definition: validatorsize.h:56
~ValidatorSize() override
Deconstructs the size validator.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message if validation failed.
ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new size validator.
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
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
int size() 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