cutelyst  4.4.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
statusmessage.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2016-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "statusmessage.h"
6 
7 #include <Cutelyst/Application>
8 #include <Cutelyst/Plugins/Session/session.h>
9 
10 #include <QRandomGenerator>
11 #include <QtCore/QDateTime>
12 #include <QtCore/QLoggingCategory>
13 
14 using namespace Cutelyst;
15 
16 Q_LOGGING_CATEGORY(C_STATUSMESSAGE, "cutelyst.plugins.statusmessage", QtWarningMsg)
17 
18 static thread_local StatusMessage *m_instance = nullptr;
19 
20 namespace Cutelyst {
21 
23 {
24 public:
25  static void _q_postFork(Application *app);
26 
27  QString sessionPrefix = QStringLiteral("status_msg");
28  QString tokenParam = QStringLiteral("mid");
29  QString statusMsgStashKey = QStringLiteral("status_msg");
30  QString errorMsgStashKey = QStringLiteral("error_msg");
31 };
32 
33 void StatusMessagePrivate::_q_postFork(Application *app)
34 {
35  m_instance = app->plugin<StatusMessage *>();
36 }
37 
38 } // namespace Cutelyst
39 
40 StatusMessage::StatusMessage(Application *parent)
41  : Plugin(parent)
42  , d_ptr(new StatusMessagePrivate)
43 {
44  m_instance = this;
45 }
46 
48 {
49  delete d_ptr;
50 }
51 
53 {
54  Q_D(const StatusMessage);
55  return d->sessionPrefix;
56 }
57 
58 void StatusMessage::setSessionPrefix(const QString &sessionPrefix)
59 {
60  Q_D(StatusMessage);
61  d->sessionPrefix = sessionPrefix;
62 }
63 
65 {
66  Q_D(const StatusMessage);
67  return d->tokenParam;
68 }
69 
70 void StatusMessage::setTokenParam(const QString &tokenParam)
71 {
72  Q_D(StatusMessage);
73  d->tokenParam = tokenParam;
74 }
75 
77 {
78  Q_D(const StatusMessage);
79  return d->statusMsgStashKey;
80 }
81 
82 void StatusMessage::setStatusMsgStashKey(const QString &statusMsgStashKey)
83 {
84  Q_D(StatusMessage);
85  d->statusMsgStashKey = statusMsgStashKey;
86 }
87 
89 {
90  Q_D(const StatusMessage);
91  return d->errorMsgStashKey;
92 }
93 
94 void StatusMessage::setErrorMgStashKey(const QString &errorMgStashKey)
95 {
96  Q_D(StatusMessage);
97  d->errorMsgStashKey = errorMgStashKey;
98 }
99 
101 {
102  if (Q_UNLIKELY(!m_instance)) {
103  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
104  return;
105  }
106  StatusMessagePrivate *priv = m_instance->d_ptr;
107 
108  const QString token = c->request()->queryParam(priv->tokenParam);
109  if (token.isEmpty()) {
110  return;
111  }
112 
113  QStringList deleteKeys;
114  const QString statusKey = priv->sessionPrefix + u"status" + token;
115  const QVariant statusValue = Session::value(c, statusKey);
116  if (!statusValue.isNull()) {
117  deleteKeys.append(statusKey);
118  c->setStash(priv->statusMsgStashKey, statusValue);
119  }
120 
121  const QString errorKey = priv->sessionPrefix + u"error" + token;
122  const QVariant errorValue = Session::value(c, errorKey);
123  if (!errorValue.isNull()) {
124  deleteKeys.append(errorKey);
125  c->setStash(priv->errorMsgStashKey, errorValue);
126  }
127 
128  if (!deleteKeys.isEmpty()) {
129  Session::deleteValues(c, deleteKeys);
130  }
131 }
132 
133 inline QString createToken()
134 {
135  return QString::number(QRandomGenerator::global()->generate() % 99999999)
136  .rightJustified(8, u'0', true);
137 }
138 
140 {
141  QString token;
142  if (Q_UNLIKELY(!m_instance)) {
143  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
144  return token;
145  }
146 
147  token = createToken();
148  Session::setValue(c, m_instance->d_ptr->sessionPrefix + u"error" + token, msg);
149  return token;
150 }
151 
153 {
154  ParamsMultiMap map(query);
155  if (Q_UNLIKELY(!m_instance)) {
156  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
157  return map;
158  }
159  StatusMessagePrivate *priv = m_instance->d_ptr;
160 
161  const QString token = createToken();
162  Session::setValue(c, priv->sessionPrefix + u"error" + token, msg);
163  map.insert(priv->tokenParam, token);
164  return map;
165 }
166 
168 {
169  QString token;
170  if (Q_UNLIKELY(!m_instance)) {
171  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
172  return token;
173  }
174 
175  token = createToken();
176  Session::setValue(c, m_instance->d_ptr->sessionPrefix + u"status" + token, msg);
177  return token;
178 }
179 
181 {
182  ParamsMultiMap map(query);
183  if (Q_UNLIKELY(!m_instance)) {
184  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
185  return map;
186  }
187  StatusMessagePrivate *priv = m_instance->d_ptr;
188 
189  const QString token = createToken();
190  Session::setValue(c, priv->sessionPrefix + u"status" + token, msg);
191  map.insert(priv->tokenParam, token);
192  return map;
193 }
194 
196 {
197  connect(app, &Application::postForked, this, &StatusMessagePrivate::_q_postFork);
198  return true;
199 }
200 
201 #include "moc_statusmessage.cpp"
The Cutelyst application.
Definition: application.h:66
void postForked(Cutelyst::Application *app)
The Cutelyst Context.
Definition: context.h:42
Request * request
Definition: context.h:71
void setStash(const QString &key, const QVariant &value)
Definition: context.cpp:212
Base class for Cutelyst Plugins.
Definition: plugin.h:25
QString queryParam(const QString &key, const QString &defaultValue={}) const
Definition: request.h:591
static QVariant value(Context *c, const QString &key, const QVariant &defaultValue=QVariant())
Definition: session.cpp:168
static void setValue(Context *c, const QString &key, const QVariant &value)
Definition: session.cpp:183
static void deleteValues(Context *c, const QStringList &keys)
Definition: session.cpp:231
Manage status messages over multiple requests stored in the Session.
Definition: statusmessage.h:85
static QString error(Context *c, const QString &msg)
static void load(Context *c)
QString errorMgStashKey() const noexcept
void setTokenParam(const QString &tokenParam)
QString statusMsgStashKey() const noexcept
virtual bool setup(Application *app) override
static QString status(Context *c, const QString &msg)
static ParamsMultiMap statusQuery(Context *c, const QString &msg, ParamsMultiMap query={})
void setErrorMgStashKey(const QString &errorMgStashKey)
QString sessionPrefix() const noexcept
void setStatusMsgStashKey(const QString &statusMsgStashKey)
QString tokenParam() const noexcept
void setSessionPrefix(const QString &sessionPrefix)
virtual ~StatusMessage() override
static ParamsMultiMap errorQuery(Context *c, const QString &msg, ParamsMultiMap query={})
The Cutelyst namespace holds all public Cutelyst API.
void append(QList::parameter_type value)
bool isEmpty() const const
QMultiMap::iterator insert(QMultiMap::const_iterator pos, const Key &key, const T &value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QRandomGenerator * global()
bool isEmpty() const const
QString number(double n, char format, int precision)
QString rightJustified(qsizetype width, QChar fill, bool truncate) const const
bool isNull() const const