Cutelyst  2.14.2
validatorafter.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 "validatorafter_p.h"
20 
21 #include <QLocale>
22 #include <QTimeZone>
23 
24 using namespace Cutelyst;
25 
26 ValidatorAfter::ValidatorAfter(const QString &field, const QVariant &comparison, const QString &timeZone, const char *inputFormat, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
27  ValidatorRule(*new ValidatorAfterPrivate(field, comparison, timeZone, inputFormat, messages, defValKey))
28 {
29 }
30 
32 {
33 
34 }
35 
37 {
38  ValidatorReturnType result;
39 
40  Q_D(const ValidatorAfter);
41 
42  const QString v = value(params);
43 
44  if (!v.isEmpty()) {
45 
46  const QTimeZone tz = d->extractTimeZone(c, params, d->timeZone);
47 
48  const QVariant _comp = (d->comparison.type() == QVariant::String)
49  ? d->extractOtherDateTime(c, params, d->comparison.toString(), tz, d->inputFormat)
50  : d->comparison;
51 
52  if (_comp.type() == QVariant::Date) {
53 
54  const QDate odate = _comp.toDate();
55  if (Q_UNLIKELY(!odate.isValid())) {
56  qCWarning(C_VALIDATOR, "ValidatorAfter: Invalid comparison date and time for field %s at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
58  } else {
59  const QDate date = d->extractDate(c, v, d->inputFormat);
60  if (Q_UNLIKELY(!date.isValid())) {
61  qCWarning(C_VALIDATOR, "ValidatorAfter: Can not parse input date \"%s\" for field %s at %s::%s.", qPrintable(v), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
62  result.errorMessage = parsingError(c, odate);
63  } else {
64  if (Q_UNLIKELY(date <= odate)) {
65  qCDebug(C_VALIDATOR, "ValidatorAfter: Validation failed at %s::%s for field %s: Input date \"%s\" is not after \"%s\".", qPrintable(c->controllerName()), qPrintable(c->actionName()), qPrintable(field()), qPrintable(date.toString()), qPrintable(odate.toString()));
66  result.errorMessage = validationError(c, odate);
67  } else {
68  result.value.setValue<QDate>(date);
69  }
70  }
71  }
72 
73  } else if (_comp.type() == QVariant::DateTime) {
74 
75  const QDateTime odatetime = _comp.toDateTime();
76  if (Q_UNLIKELY(!odatetime.isValid())) {
77  qCWarning(C_VALIDATOR, "ValidatorAfter: Invalid comparison date and time for field %s at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
79  } else {
80  const QDateTime datetime = d->extractDateTime(c, v, d->inputFormat, tz);
81  if (Q_UNLIKELY(!datetime.isValid())) {
82  qCWarning(C_VALIDATOR, "ValidatorAfter: Can not parse input date and time \"%s\" for field %s at %s::%s.", qPrintable(v), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
83  result.errorMessage = parsingError(c, odatetime);
84  } else {
85  if (Q_UNLIKELY(datetime <= odatetime)) {
86  qCDebug(C_VALIDATOR, "ValidatorAfter: Validation failed at %s::%s for field %s: Input date and time \"%s\" is not after \"%s\".", qPrintable(c->controllerName()), qPrintable(c->actionName()), qPrintable(field()), qPrintable(datetime.toString()), qPrintable(odatetime.toString()));
87  result.errorMessage = validationError(c, odatetime);
88  } else {
89  result.value.setValue<QDateTime>(datetime);
90  }
91  }
92  }
93 
94  } else if (_comp.type() == QVariant::Time) {
95 
96  const QTime otime = _comp.toTime();
97  if (Q_UNLIKELY(!otime.isValid())) {
98  qCWarning(C_VALIDATOR, "ValidatorAfter: Invalid comparison time for field %s at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
100  } else {
101  const QTime time = d->extractTime(c, v, d->inputFormat);
102  if (Q_UNLIKELY(!time.isValid())) {
103  qCWarning(C_VALIDATOR, "ValidatorAfter: Can not parse input time \"%s\" for field %s at %s::%s.", qPrintable(v), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
104  result.errorMessage = parsingError(c, otime);
105  } else {
106  if (Q_UNLIKELY(time <= otime)) {
107  qCDebug(C_VALIDATOR, "ValidatorAfter: Validation failed at %s::%s for field %s: Input time \"%s\" is not after \"%s\".", qPrintable(c->controllerName()), qPrintable(c->actionName()), qPrintable(field()), qPrintable(time.toString()), qPrintable(otime.toString()));
108  result.errorMessage = validationError(c, otime);
109  } else {
110  result.value.setValue<QTime>(time);
111  }
112  }
113  }
114 
115  } else {
116  qCWarning(C_VALIDATOR) << "ValidatorAfter: Invalid validation data for field" << field() << "at" << c->controllerName() << "::" << c->actionName() << ":" << d->comparison;
117  result.errorMessage = validationDataError(c);
118  }
119  } else {
120  defaultValue(c, &result, "ValidatorAfter");
121  }
122 
123  return result;
124 }
125 
127 {
128  QString error;
129 
130  const QString _label = label(c);
131  if (_label.isEmpty()) {
132 
133  switch (errorData.type()) {
134  case QVariant::Date:
135  error = QStringLiteral("Has to be after %1.").arg(errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
136  break;
137  case QVariant::DateTime:
138  error = QStringLiteral("Has to be after %1.").arg(errorData.toDateTime().toString(c->locale().dateTimeFormat(QLocale::ShortFormat)));
139  break;
140  case QVariant::Time:
141  error = QStringLiteral("Has to be after %1.").arg(errorData.toTime().toString(c->locale().timeFormat(QLocale::ShortFormat)));
142  break;
143  default:
144  error = validationDataError(c);
145  break;
146  }
147 
148  } else {
149 
150  switch(errorData.type()) {
151  case QVariant::Date:
152  error = c->translate("Cutelyst::ValidatorAfter", "The date in the “%1” field must be after %2.").arg(_label, errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
153  break;
154  case QVariant::DateTime:
155  error = c->translate("Cutelyst::ValidatorAfter", "The date and time in the “%1” field must be after %2.").arg(_label, errorData.toDateTime().toString(c->locale().dateTimeFormat(QLocale::ShortFormat)));
156  break;
157  case QVariant::Time:
158  error = c->translate("Cutelyst::ValidatorAfter", "The time in the “%1” field must be after %2.").arg(_label, errorData.toTime().toString(c->locale().timeFormat(QLocale::ShortFormat)));
159  break;
160  default:
161  error = validationDataError(c);
162  break;
163  }
164 
165  }
166 
167  return error;
168 }
169 
171 {
172  QString error;
173 
174  Q_UNUSED(errorData)
175  error = c->translate("Cutelyst::ValidatorAfter", "The comparison value is not a valid date and/or time, or cannot be found.");
176 
177  return error;
178 }
179 
181 {
182  QString error;
183 
184  Q_D(const ValidatorAfter);
185 
186  const QString _label = label(c);
187  if (d->inputFormat) {
188  if (_label.isEmpty()) {
189  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed according to the follwing date and/or time format: %1").arg(c->translate(d->translationContext.data(), d->inputFormat));
190  } else {
191  error = c->translate("Cutelyst::ValidatorAfter", "The value of the “%1” field could not be parsed according to the follwing date and/or time format: %2").arg(_label, c->translate(d->translationContext.data(), d->inputFormat));
192  }
193  } else {
194 
195  if (_label.isEmpty()) {
196  switch (errorData.type()) {
197  case QVariant::DateTime:
198  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as date and time.");
199  break;
200  case QVariant::Time:
201  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as time.");
202  break;
203  case QVariant::Date:
204  error = c->translate("Cutelyst::ValidatorAfter", "Could not be parsed as date.");
205  break;
206  default:
207  error = validationDataError(c);
208  break;
209  }
210  } else {
211  switch (errorData.type()) {
212  case QVariant::DateTime:
213  //: %1 will be replaced by the field label
214  error = c->translate("Cutelyst::ValidatorAfter", "The value in the “%1” field could not be parsed as date and time.").arg(_label);
215  break;
216  case QVariant::Time:
217  //: %1 will be replaced by the field label
218  error = c->translate("Cutelyst::ValidatorAfter", "The value in the “%1” field could not be parsed as time.").arg(_label);
219  break;
220  case QVariant::Date:
221  //: %1 will be replaced by the field label
222  error = c->translate("Cutelyst::ValidatorAfter", "The value in the “%1” field could not be parsed as date.").arg(_label);
223  break;
224  default:
225  error = validationDataError(c);
226  break;
227  }
228  }
229  }
230 
231  return error;
232 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if validation failed.
QString toString(Qt::DateFormat format) const const
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.
QString toString(Qt::DateFormat format) const const
QString toString(Qt::DateFormat format) const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
Stores custom error messages and the input field label.
QDateTime toDateTime() const const
QTime toTime() const const
bool isValid() const const
Checks if a date, time or datetime is after a comparison value.
QLocale locale() const
Definition: context.cpp:457
The Cutelyst Context.
Definition: context.h:51
QString timeFormat(QLocale::FormatType format) const const
bool isEmpty() const const
~ValidatorAfter() override
Deconstructs the after validator.
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:481
bool isValid() const const
QString genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if the input value could not be parsed.
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.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
ValidatorAfter(const QString &field, const QVariant &comparison, const QString &timeZone=QString(), const char *inputFormat=nullptr, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new after validator.
void setValue(const T &value)
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
bool isValid() const const
QString dateFormat(QLocale::FormatType format) const const
QDate toDate() const const
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if comparison data was invalid.
QString field() const
Returns the name of the field to validate.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:62
QVariant::Type type() const const
QString dateTimeFormat(QLocale::FormatType format) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
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 ...