cutelyst  4.4.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
viewemailtemplate.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2015-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "viewemailtemplate_p.h"
6 
7 #include <Cutelyst/Context>
8 #include <SimpleMail/emailaddress.h>
9 #include <SimpleMail/mimemessage.h>
10 #include <SimpleMail/mimetext.h>
11 
12 #include <QtCore/QLoggingCategory>
13 
14 Q_LOGGING_CATEGORY(CUTELYST_VIEW_EMAILTEMPLATE, "cutelyst.view.emailtemplate", QtWarningMsg)
15 
16 using namespace Cutelyst;
17 
19  : ViewEmail(new ViewEmailTemplatePrivate, parent, name)
20 {
21  Q_D(ViewEmailTemplate);
22 
23  d->defaultContentType = QByteArrayLiteral("text/html");
24 }
25 
27 {
28  Q_D(const ViewEmailTemplate);
29  return d->templatePrefix;
30 }
31 
33 {
34  Q_D(ViewEmailTemplate);
35  d->templatePrefix = prefix;
36  Q_EMIT changedProp();
37 }
38 
40 {
41  Q_D(const ViewEmailTemplate);
42  return d->defaultView;
43 }
44 
46 {
47  Q_D(ViewEmailTemplate);
48  d->defaultView = view;
49  Q_EMIT changedProp();
50 }
51 
52 std::shared_ptr<MimePart>
53  generatePart(Context *c, const ViewEmailTemplatePrivate *d, const QVariantHash &partHash)
54 {
55  const QString defaultView = d->defaultView;
56 
57  View *view = nullptr;
58  auto viewIt = partHash.constFind(QStringLiteral("view"));
59  if (viewIt != partHash.constEnd() && !viewIt.value().toString().isEmpty()) {
60  // use the view specified for the email part
61  const QString viewString = viewIt.value().toString();
62  qCDebug(CUTELYST_VIEW_EMAILTEMPLATE)
63  << "Using specified view" << viewString << "for rendering.";
64  view = c->view(viewString);
65  } else if (!defaultView.isEmpty()) {
66  // if none specified use the configured default view
67  qCDebug(CUTELYST_VIEW_EMAILTEMPLATE)
68  << "Using default view" << defaultView << "for rendering.";
69  view = c->view(defaultView);
70  } else {
71  // else fallback to Cutelysts default view
72  qCDebug(CUTELYST_VIEW_EMAILTEMPLATE) << "Using Cutelysts default view for rendering.";
73  view = c->view(QString());
74  }
75 
76  // validate the per template view
77  if (!view) {
78  c->appendError(QStringLiteral("Could not find a view to render"));
79  return nullptr;
80  }
81 
82  QString templateString = partHash.value(QStringLiteral("template")).toString();
83  ;
84  // prefix with template_prefix if configured
85  if (!d->templatePrefix.isEmpty()) {
86  templateString = d->templatePrefix + QLatin1Char('/') + templateString;
87  }
88 
89  // render the email part
90  const QVariantHash currentStash = c->stash();
91  c->stash(partHash);
92  c->setStash(QStringLiteral("template"), templateString);
93  QByteArray output = view->render(c);
94  if (c->error()) {
95  qCDebug(CUTELYST_VIEW_EMAILTEMPLATE) << "Errors" << c->errors();
96  }
97  c->stash() = currentStash;
98 
99  auto part = std::make_shared<MimePart>();
100  part->setContent(output);
101 
102  d->setupAttributes(part, partHash);
103 
104  return part;
105 }
106 
108 {
109  Q_D(const ViewEmailTemplate);
110 
111  QByteArray ret;
112  QVariantHash email = c->stash(d->stashKey).toHash();
113  const QString templateName = email.value(QStringLiteral("template")).toString();
114  const QVariantList templateList = email.value(QStringLiteral("templates")).toList();
115  if (templateName.isEmpty() && templateList.isEmpty()) {
116  ret = ViewEmail::render(c);
117  return ret;
118  }
119 
120  QVariantList parts = email.value(QStringLiteral("parts")).toList();
121  if (!templateList.isEmpty() && templateList.first().typeId() == QMetaType::QVariantHash) {
122  // multipart API
123  for (const QVariant &part : templateList) {
124  const QVariantHash partHash = part.toHash();
125  auto partObj = generatePart(c, d, partHash);
126  parts.append(QVariant::fromValue(partObj));
127  }
128 
129  } else if (!templateName.isEmpty()) {
130  // single part API
131  QVariantHash partArgs({
132  {QStringLiteral("template"), templateName},
133 
134  });
135  auto contentTypeIt = email.constFind(QStringLiteral("content_type"));
136  if (contentTypeIt != email.constEnd() && !contentTypeIt.value().toString().isEmpty()) {
137  partArgs.insert(QStringLiteral("content_type"), contentTypeIt.value().toString());
138  }
139  auto partObj = generatePart(c, d, partArgs);
140  parts.append(QVariant::fromValue(partObj));
141  }
142  email.insert(QStringLiteral("parts"), parts);
143  c->setStash(d->stashKey, email);
144 
145  ret = ViewEmail::render(c);
146  return ret;
147 }
148 
149 #include "moc_viewemailtemplate.cpp"
The Cutelyst Context.
Definition: context.h:42
QStringList errors() const noexcept
Definition: context.cpp:67
void stash(const QVariantHash &unite)
Definition: context.cpp:562
void setStash(const QString &key, const QVariant &value)
Definition: context.cpp:212
View * view(QStringView name={}) const
Definition: context.cpp:169
void appendError(const QString &error)
Definition: context.cpp:56
bool error() const noexcept
Definition: context.cpp:50
A view that renders stash data using another view and sends it via e-mail.
void setDefaultView(const QString &view)
QByteArray render(Context *c) const override
ViewEmailTemplate(QObject *parent, const QString &name=QString())
void setTemplatePrefix(const QString &prefix)
A view that sends stash data via e-mail.
Definition: viewemail.h:24
QByteArray render(Context *c) const override
Definition: viewemail.cpp:152
Abstract View component for Cutelyst.
Definition: view.h:25
virtual QByteArray render(Context *c) const =0
The Cutelyst namespace holds all public Cutelyst API.
Q_EMITQ_EMIT
bool isEmpty() const const
QVariant fromValue(T &&value)