diff --git a/config/routes.php b/config/routes.php index 76f360b57..75dea7db1 100644 --- a/config/routes.php +++ b/config/routes.php @@ -535,6 +535,13 @@ ['_name' => 'lock:remove'], ); + // SendMail + $routes->connect( + '/sendmail', + ['controller' => 'SendMail', 'action' => 'index'], + ['_name' => 'sendmail:index'], + ); + // Session $routes->get( '/session/{name}', diff --git a/locales/default.pot b/locales/default.pot index 9199b4de5..2d3c04601 100644 --- a/locales/default.pot +++ b/locales/default.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: BEdita 4 \n" -"POT-Creation-Date: 2025-08-26 08:17:45 \n" +"POT-Creation-Date: 2025-10-29 11:08:16 \n" "MIME-Version: 1.0 \n" "Content-Transfer-Encoding: 8bit \n" "Language-Team: BEdita I18N & I10N Team \n" @@ -1765,6 +1765,9 @@ msgstr "" msgid "View original" msgstr "" +msgid "Send" +msgstr "" + msgid "Address" msgstr "" diff --git a/locales/en_US/default.po b/locales/en_US/default.po index 4fea704f5..04a352a16 100644 --- a/locales/en_US/default.po +++ b/locales/en_US/default.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: BEdita Manager \n" -"POT-Creation-Date: 2025-08-26 08:17:45 \n" +"POT-Creation-Date: 2025-10-29 11:08:16 \n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: BEdita I18N & I10N Team \n" @@ -1768,6 +1768,9 @@ msgstr "" msgid "View original" msgstr "" +msgid "Send" +msgstr "" + msgid "Address" msgstr "" diff --git a/locales/it_IT/default.po b/locales/it_IT/default.po index 9ab7d401b..bf1b9d702 100644 --- a/locales/it_IT/default.po +++ b/locales/it_IT/default.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: BEdita Manager \n" -"POT-Creation-Date: 2025-08-26 08:17:45 \n" +"POT-Creation-Date: 2025-10-29 11:08:16 \n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: BEdita I18N & I10N Team \n" @@ -1791,6 +1791,9 @@ msgstr "" msgid "View original" msgstr "Vedi originale" +msgid "Send" +msgstr "Invia" + msgid "Address" msgstr "Indirizzo" diff --git a/resources/js/app/app.js b/resources/js/app/app.js index 746b02120..23488317e 100644 --- a/resources/js/app/app.js +++ b/resources/js/app/app.js @@ -117,6 +117,7 @@ const _vueInstance = new Vue({ AddRelatedById: () => import(/* webpackChunkName: "add-related-by-id" */'app/components/add-related-by-id/add-related-by-id'), UploadedObject: () => import(/* webpackChunkName: "uploaded-object" */'app/components/uploaded-object/uploaded-object.vue'), RibbonItem: () => import(/* webpackChunkName: "ribbon-item" */'./components/ribbon-item/ribbon-item.vue'), + MailPreview: () => import(/* webpackChunkName: "mail-preview" */'./components/mail-preview/mail-preview.vue'), AppIcon, }, diff --git a/resources/js/app/components/mail-preview/mail-preview.vue b/resources/js/app/components/mail-preview/mail-preview.vue new file mode 100644 index 000000000..32f41e8b6 --- /dev/null +++ b/resources/js/app/components/mail-preview/mail-preview.vue @@ -0,0 +1,122 @@ + + + diff --git a/resources/js/app/components/property-view/property-view.js b/resources/js/app/components/property-view/property-view.js index 101f1c6d6..ce61517e4 100644 --- a/resources/js/app/components/property-view/property-view.js +++ b/resources/js/app/components/property-view/property-view.js @@ -48,6 +48,7 @@ export default { ObjectCategories: () => import(/* webpackChunkName: "object-categories" */'app/components/object-categories/object-categories'), PlaceholderList: () => import(/* webpackChunkName: "placeholder-list" */'app/components/placeholder-list/placeholder-list'), MediaItem: () => import(/* webpackChunkName: "media-item" */'app/components/media-item/media-item'), + MailPreview: () => import(/* webpackChunkName: "mail-preview" */'app/components/mail-preview/mail-preview.vue'), }, props: { diff --git a/resources/js/app/pages/modules/view.vue b/resources/js/app/pages/modules/view.vue index a76daee3b..6695d1e6a 100644 --- a/resources/js/app/pages/modules/view.vue +++ b/resources/js/app/pages/modules/view.vue @@ -16,6 +16,7 @@ export default { KeyValueList: () => import(/* webpackChunkName: "key-value-list" */'app/components/json-fields/key-value-list'), StringList: () => import(/* webpackChunkName: "string-list" */'app/components/json-fields/string-list'), LanguageSelector:() => import(/* webpackChunkName: "language-selector" */'app/components/language-selector/language-selector'), + MailPreview: () => import(/* webpackChunkName: "mail-preview" */'app/components/mail-preview/mail-preview.vue'), }, props: { diff --git a/src/Controller/SendMailController.php b/src/Controller/SendMailController.php new file mode 100644 index 000000000..2abdd2ba7 --- /dev/null +++ b/src/Controller/SendMailController.php @@ -0,0 +1,48 @@ +FormProtection->setConfig('unlockedActions', ['index']); + } + + /** + * @inheritDoc + */ + public function index(): void + { + $this->getRequest()->allowMethod(['post']); + $this->viewBuilder()->setClassName('Json'); + try { + $payload = $this->getRequest()->getData(); + foreach ($payload['data'] as $key => $value) { + if (strpos($key, '.') !== false) { + unset($payload['data'][$key]); + $payload['data'] = Hash::insert($payload['data'], $key, $value); + } + } + ApiClientProvider::getApiClient()->post('/placeholders/send', (string)json_encode($payload)); + $response = ['message' => 'Email sent successfully']; + $this->set('response', $response); + $this->setSerialize(['response']); + } catch (Exception $e) { + $this->set('error', $e->getMessage()); + $this->setSerialize(['error']); + } + } +} diff --git a/templates/Element/Form/mail_preview.twig b/templates/Element/Form/mail_preview.twig new file mode 100644 index 000000000..080d29233 --- /dev/null +++ b/templates/Element/Form/mail_preview.twig @@ -0,0 +1,2 @@ + + diff --git a/tests/TestCase/Controller/SendMailControllerTest.php b/tests/TestCase/Controller/SendMailControllerTest.php new file mode 100644 index 000000000..78c11aef0 --- /dev/null +++ b/tests/TestCase/Controller/SendMailControllerTest.php @@ -0,0 +1,60 @@ + [ + 'REQUEST_METHOD' => 'POST', + ], + 'post' => [ + 'data' => [ + 'user.name' => 'John', + 'user.surname' => 'Doe', + ], + ], + ]; + $request = new ServerRequest($config); + $controller = new SendMailController($request); + $controller->index(); + $expected = '[404] Not Found'; + $actual = $controller->viewBuilder()->getVar('error'); + static::assertEquals($expected, $actual); + + // mock /placeholders/send to simulate success response + $safeClient = ApiClientProvider::getApiClient(); + $apiClient = $this->getMockBuilder(BEditaClient::class) + ->setConstructorArgs(['https://api.example.org']) + ->getMock(); + $apiClient->method('post') + ->willReturn(null); + ApiClientProvider::setApiClient($apiClient); + $controller->index(); + $expected = 'Email sent successfully'; + $actual = $controller->viewBuilder()->getVar('response')['message']; + static::assertEquals($expected, $actual); + ApiClientProvider::setApiClient($safeClient); + } +}