Cutelyst  2.14.2
validatorbefore.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 "validatorbefore_p.h"
20 
21 #include <QtCore/QLoggingCategory>
22 
23 using namespace Cutelyst;
24 
25 Q_LOGGING_CATEGORY(C_VALIDATORBEFORE, "cutelyst.utils.validator.before", QtWarningMsg)
26 
27 ValidatorBefore::ValidatorBefore(const QString &field, const QVariant &comparison, const QString &timeZone, const char *inputFormat, const ValidatorMessages &messages, const QString &defValKey) :
28  ValidatorRule(*new ValidatorBeforePrivate(field, comparison, timeZone, inputFormat, messages, defValKey))
29 {
30 }
31 
33 {
34 }
35 
37 {
38  ValidatorReturnType result;
39 
40  Q_D(const ValidatorBefore);
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, "ValidatorBefore: 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, "ValidatorBefore: 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, "ValidatorBefore: Validation failed at %s::%s for field %s: Input date \"%s\" is not before \"%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, "ValidatorBefore: 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, "ValidatorBefore: 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, "ValidatorBefore: Validation failed at %s::%s for field %s: Input date and time \"%s\" is not before \"%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, "ValidatorBefore: 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, "ValidatorBefore: 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, "ValidatorBefore: Validation failed at %s::%s for field %s: Input time \"%s\" is not before \"%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) << "ValidatorBefore: 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 before %1.").arg(errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
136  break;
137  case QVariant::DateTime:
138  error = QStringLiteral("Has to be before %1.").arg(errorData.toDateTime().toString(c->locale().dateTimeFormat(QLocale::ShortFormat)));
139  break;
140  case QVariant::Time:
141  error = QStringLiteral("Has to be before %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::ValidatorBefore", "The date in the “%1” field must be before %2.").arg(_label, errorData.toDate().toString(c->locale().dateFormat(QLocale::ShortFormat)));
153  break;
154  case QVariant::DateTime:
155  error = c->translate("Cutelyst::ValidatorBefore", "The date and time in the “%1” field must be before %2.").arg(_label, errorData.toDateTime().toString(c->locale().dateTimeFormat(QLocale::ShortFormat)));
156  break;
157  case QVariant::Time:
158  error = c->translate("Cutelyst::ValidatorBefore", "The time in the “%1” field must be before %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::ValidatorBefore", "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 ValidatorBefore);
185 
186  const QString _label = label(c);
187  if (d->inputFormat) {
188  if (_label.isEmpty()) {
189  //: %1 will be replaced by the datetime format
190  error = c->translate("Cutelyst::ValidatorBefore", "Could not be parsed according to the follwing date and/or time format: %1").arg(c->translate(d->translationContext.data(), d->inputFormat));
191  } else {
192  //: %1 will be replaced by the field label, %2 will be replaced by the datetime format
193  error = c->translate("Cutelyst::ValidatorBefore", "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));
194  }
195  } else {
196 
197  if (_label.isEmpty()) {
198  switch (errorData.type()) {
199  case QVariant::DateTime:
200  error = c->translate("Cutelyst::ValidatorBefore", "Could not be parsed as date and time.");
201  break;
202  case QVariant::Time:
203  error = c->translate("Cutelyst::ValidatorBefore", "Could not be parsed as time.");
204  break;
205  case QVariant::Date:
206  error = c->translate("Cutelyst::ValidatorBefore", "Could not be parsed as date.");
207  break;
208  default:
209  error = validationDataError(c);
210  break;
211  }
212  } else {
213  switch (errorData.type()) {
214  case QVariant::DateTime:
215  //: %1 will be replaced by the field label
216  error = c->translate("Cutelyst::ValidatorBefore", "The value in the “%1” field could not be parsed as date and time.").arg(_label);
217  break;
218  case QVariant::Time:
219  //: %1 will be replaced by the field label
220  error = c->translate("Cutelyst::ValidatorBefore", "The value in the “%1” field could not be parsed as time.").arg(_label);
221  break;
222  case QVariant::Date:
223  //: %1 will be replaced by the field label
224  error = c->translate("Cutelyst::ValidatorBefore", "The value in the “%1” field could not be parsed as date.").arg(_label);
225  break;
226  default:
227  error = validationDataError(c);
228  break;
229  }
230  }
231  }
232 
233  return error;
234 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if validation failed.
QString toString(Qt::DateFormat format) const
QString field() const
Returns the name of the field to validate.
QString toString(Qt::DateFormat format) const
QString toString(Qt::DateFormat format) const
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
Stores custom error messages and the input field label.
QDateTime toDateTime() const
QTime toTime() const
bool isValid() const
The Cutelyst Context.
Definition: context.h:51
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
QString timeFormat(FormatType format) const
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
bool isEmpty() const
QString genericValidationDataError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if comparison data was invalid.
bool isValid() const
Base class for all validator rules.
Checks if a date, time or datetime is before a comparison value.
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 ...
void setValue(const T &value)
QLocale locale() const
Definition: context.cpp:457
bool isValid() const
QString dateFormat(FormatType format) const
QDate toDate() const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:481
Contains the result of a single input parameter validation.
Definition: validatorrule.h:62
~ValidatorBefore() override
Deconstructs the before validator.
QString genericParsingError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if the input value could not be parsed.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
Type type() const
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
QString dateTimeFormat(FormatType format) const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occured while parsing input.