Finished mailer
This commit is contained in:
parent
70c0a92595
commit
da55c23343
|
@ -74,9 +74,9 @@ module.exports = function (grunt) {
|
|||
mangle: true,
|
||||
report: 'gzip',
|
||||
compress: {
|
||||
drop_console: true
|
||||
drop_console: false
|
||||
},
|
||||
banner: '/*! \n * Resume.PHP - v<%= pkg.version %> @license MIT (http://resume.reric.me)\n' +
|
||||
banner: '/*! \n * Resume.PHP - v<%= pkg.version %> MIT (http://resume.reric.me)\n' +
|
||||
' * <%= grunt.template.today("dddd, mmmm dS, yyyy, h:MM:ss tt") %> \n */\n',
|
||||
footer: '\n/*! Resume.PHP end */',
|
||||
nameCache: '.tmp/grunt-uglify-cache.json',
|
||||
|
|
|
@ -9,8 +9,4 @@ app:
|
|||
captcha: true
|
||||
captcha_sitekey: 6LcvmSQTAAAAAMmf9w6mhCbpdLvknuD9SGVHT0q-
|
||||
captcha_secret: 6LcvmSQTAAAAAITkvYJjgLar1LqGGLz-ic0ZMiXo
|
||||
twig_theme: default
|
||||
twig_paths:
|
||||
- views
|
||||
- default
|
||||
twig_template: uikit.html.twig
|
||||
theme: default
|
||||
|
|
|
@ -8,8 +8,8 @@ app:
|
|||
captcha: true
|
||||
captcha_sitekey: 6LcvmSQTAAAAAMmf9w6mhCbpdLvknuD9SGVHT0q-
|
||||
captcha_secret: 6LcvmSQTAAAAAITkvYJjgLar1LqGGLz-ic0ZMiXo
|
||||
twig_theme: default
|
||||
twig_paths:
|
||||
- views
|
||||
twig_template: uikit.html.twig
|
||||
theme: default
|
||||
#twig_paths:
|
||||
# - views
|
||||
#twig_template: uikit.html.twig
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Resume.PHP.
|
||||
*
|
||||
* (copyleft) R. Eric Wheeler <sikofitt@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'app' => 'neat',
|
||||
];
|
|
@ -38,11 +38,10 @@ $app->register(new ConfigServiceProvider(), [
|
|||
|
||||
$app->setDebug();
|
||||
|
||||
|
||||
$app
|
||||
->register(new TwigServiceProvider(), [
|
||||
'twig.path' => [
|
||||
$app->getRootDirectory() . '/app/views',
|
||||
],
|
||||
'twig.path' => $app->getAppDirectory() . '/themes/' . $app->config('app.theme'),
|
||||
])
|
||||
->register(new JsonServiceProvider())
|
||||
->register(new AssetServiceProvider())
|
||||
|
@ -59,7 +58,22 @@ $app
|
|||
'monolog.name' => 'Resume.PHP',
|
||||
'monolog.level' => $app->getDebug() ? Logger::DEBUG : Logger::INFO,
|
||||
])
|
||||
->register(new RoutingServiceProvider())
|
||||
->register(new \Silex\Provider\SwiftmailerServiceProvider());
|
||||
|
||||
if(false === getenv('SPARKPOST_API_KEY')) {
|
||||
$app['swiftmailer.transport'] = new Swift_SendmailTransport();
|
||||
} else {
|
||||
$app['swiftmailer.options'] = [
|
||||
'host' => getenv('SPARKPOST_SMTP_HOST'),
|
||||
'port' => getenv('SPARKPOST_SMTP_PORT'),
|
||||
'username' => getenv('SPARKPOST_SMTP_USERNAME'),
|
||||
'password' => getenv('SPARKPOST_SMTP_PASSWORD'),
|
||||
'encryption' => 'tls',
|
||||
'auth_mode' => 'plain',
|
||||
];
|
||||
}
|
||||
|
||||
$app->register(new RoutingServiceProvider())
|
||||
->register(new ServiceControllerServiceProvider())
|
||||
->register(new HttpFragmentServiceProvider());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends app.config.twig.template %}
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{{ app.config.app.title | default('Resume') }}
|
||||
|
@ -175,10 +175,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="uk-form-row">
|
||||
{{ form_label(contact_form.message) }}
|
||||
{{ form_label(contact_form.message|raw) }}
|
||||
<div class="uk-form-controls">
|
||||
{{ form_widget(contact_form.message, {'attr':{'placeholder': "Please leave me a message. I will get back to you as soon as possible."}}) }} </div>
|
||||
|
||||
{{ form_widget(contact_form.message) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-form-row">
|
||||
{{ form_label(contact_form.submit) }}
|
||||
|
@ -207,7 +207,7 @@
|
|||
<h1>Verify</h1>
|
||||
<div>
|
||||
<p> Verify that you are a human please.</p>
|
||||
<form class="uk-form" id="recaptcha" method="post" action="/api/v1/captcha"
|
||||
<form class="uk-form" id="recaptcha" method="post" action="{{ path('api_captcha') }}"
|
||||
onsubmit="return false;">
|
||||
<div class="uk-form-row">
|
||||
<div class="g-recaptcha" data-sitekey="6LcvmSQTAAAAAMmf9w6mhCbpdLvknuD9SGVHT0q-"></div>
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "58b6f8f80e5846af7b9ae23a628a0861",
|
||||
"hash": "e690fdd7168c515136615a9ee42053de",
|
||||
"content-hash": "9d13427d982ec276ccfba5e7fdc2cd8a",
|
||||
"packages": [
|
||||
{
|
||||
|
|
|
@ -24,15 +24,23 @@
|
|||
|
||||
namespace Sikofitt\Controller;
|
||||
|
||||
use Prophecy\Doubler\ClassPatch\ReflectionClassNewInstancePatch;
|
||||
use ReCaptcha\ReCaptcha;
|
||||
use Sikofitt\Form\Type\ContactType;
|
||||
use Silex\Api\ControllerProviderInterface;
|
||||
use Silex\Application;
|
||||
use Silex\Provider\SecurityServiceProvider;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Validator\Constraints\Collection;
|
||||
use Symfony\Component\Validator\Constraints\Email;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\Constraints\EqualTo;
|
||||
use Symfony\Component\Validator\ValidatorBuilder;
|
||||
|
||||
class ApiControllerProvider implements ControllerProviderInterface
|
||||
{
|
||||
class ApiControllerProvider implements ControllerProviderInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
@ -40,26 +48,130 @@ class ApiControllerProvider implements ControllerProviderInterface
|
|||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect(Application $app)
|
||||
{
|
||||
public function connect(Application $app) {
|
||||
$controllers = $app['controllers_factory'];
|
||||
|
||||
|
||||
|
||||
$controllers->get('/v1/schema', function () use ($app) {
|
||||
|
||||
$response = new Response(file_get_contents($app->getDataDirectory() . '/schema/schema.v1.json'), Response::HTTP_OK);
|
||||
$response->headers->set('Content-Type', 'application/schema+json');
|
||||
|
||||
return $response;
|
||||
});
|
||||
|
||||
$controllers->match('/v1/message', function (Request $request) use ($app) {
|
||||
/*$app->mail(\Swift_Message::newInstance()
|
||||
->setSubject('[YourSite] Feedback')
|
||||
->setFrom(array('noreply@yoursite.com'))
|
||||
->setTo(array('feedback@yoursite.com'))
|
||||
->setBody($request->get('message'))); */
|
||||
return new Response('This is the message.');
|
||||
})->method('GET|POST');
|
||||
|
||||
static $code = 255;
|
||||
$returnData = [
|
||||
'status' => 'error',
|
||||
'message' => 'Unknown error.',
|
||||
'code' => $code,
|
||||
];
|
||||
$csrf = $request->getSession()->get('_csrf/contact') ?: false;
|
||||
|
||||
// Set some validation constraints
|
||||
$constraints = [
|
||||
'contact' => new Collection([
|
||||
'name' => [
|
||||
new Length([
|
||||
'min' => 4,
|
||||
'minMessage' => 'Name must be at least 4 characters.',
|
||||
]
|
||||
),
|
||||
new NotBlank([
|
||||
'message' => 'Name must not be blank.',
|
||||
]
|
||||
),
|
||||
],
|
||||
'email' => [
|
||||
new Email([
|
||||
'message' => 'Invalid email',
|
||||
]),
|
||||
new NotBlank([
|
||||
'message' => 'Email must not be blank.',
|
||||
]),
|
||||
],
|
||||
'message' => [
|
||||
new Length([
|
||||
'min' => 20,
|
||||
'minMessage' => 'Message must be at least 20 characters.',
|
||||
]),
|
||||
new NotBlank([
|
||||
'message' => 'Message must not be blank',
|
||||
]),
|
||||
],
|
||||
'_token' => [
|
||||
new EqualTo(['value' => $csrf, 'message' => 'Invalid token.']),
|
||||
]
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
$contactFormData = $request->request->all();
|
||||
|
||||
$valid = $app['validator']->validate($contactFormData, new Collection($constraints));
|
||||
|
||||
if(count($valid) > 0) {
|
||||
$sanitizeProperty = function() use ($valid) {
|
||||
return str_replace(['][', '[', ']'], ['_','',''], $valid[0]->getPropertyPath());
|
||||
};
|
||||
|
||||
return new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => $valid[0]->getMessage(),
|
||||
'id' => $sanitizeProperty(),
|
||||
'const' => $valid[0]->getCode(),
|
||||
'code' => 256
|
||||
], 256);
|
||||
|
||||
} else {
|
||||
|
||||
$contactFormName = $contactFormData['contact']['name'];
|
||||
$contactFormEmail = $contactFormData['contact']['email'];
|
||||
$contactFormMessage = $contactFormData['contact']['message'];
|
||||
$request->getSession()->remove('_csrf/contact');
|
||||
|
||||
try {
|
||||
$app->mail(\Swift_Message::newInstance()
|
||||
->setSubject('[Resume] Message')
|
||||
->setFrom([$contactFormEmail => $contactFormName])
|
||||
->setTo($app->config('app.email'))
|
||||
->setBody($contactFormMessage)
|
||||
);
|
||||
$returnData = [
|
||||
'status' => 'success',
|
||||
'message' => 'Message successfully sent.',
|
||||
'code' => 201,
|
||||
'data' => $contactFormData,
|
||||
];
|
||||
} catch(\Exception $e) {
|
||||
$returnData = [
|
||||
'status' => 'error',
|
||||
'message' => 'Could not send message.',
|
||||
'code' => 256,
|
||||
'data' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
return new JsonResponse($returnData, 201);
|
||||
}
|
||||
|
||||
})->method('GET|POST')->bind('api_message');
|
||||
$controllers->get('/v1/emailTest', function(Request $request) use ($app) {
|
||||
try {
|
||||
$app->mail(\Swift_Message::newInstance()
|
||||
->setSubject('[Resume] Message')
|
||||
->setFrom(['eric@rewiv.com' => 'Eric'])
|
||||
->setTo('eric@ericwheeler.net')
|
||||
->setBody('Testing message.')
|
||||
);
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
dump($e->getMessage());
|
||||
}
|
||||
return new Response('Hello');
|
||||
});
|
||||
|
||||
$controllers->post('/v1/captcha', function (Request $request) use ($app) {
|
||||
$captcha = new ReCaptcha('6LcvmSQTAAAAAITkvYJjgLar1LqGGLz-ic0ZMiXo');
|
||||
|
||||
|
@ -75,12 +187,13 @@ class ApiControllerProvider implements ControllerProviderInterface
|
|||
'phone' => null !== $app->config('app.phone') ? $app->config('app.phone') : 'No phone has been set in the configuration. Please let the owner know.',
|
||||
],
|
||||
];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$errorCodes = [
|
||||
'missing-input-secret' => 'The secret parameter is missing.',
|
||||
'invalid-input-secret' => 'The secret parameter is invalid or malformed.',
|
||||
'missing-input-response' => 'The response parameter is missing.',
|
||||
'invalid-input-response' => 'The response parameter is invalid or malformed.'
|
||||
'invalid-input-response' => 'The response parameter is invalid or malformed.',
|
||||
];
|
||||
|
||||
foreach ($valid->getErrorCodes() as $code) {
|
||||
|
@ -98,7 +211,7 @@ class ApiControllerProvider implements ControllerProviderInterface
|
|||
}
|
||||
|
||||
return new JsonResponse(json_encode($return));
|
||||
});
|
||||
})->bind('api_captcha');
|
||||
|
||||
return $controllers;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class ResumeControllerProvider implements ControllerProviderInterface
|
|||
|
||||
$controllers->get('/', function (Request $request) use ($app, $contactForm) {
|
||||
|
||||
return $app['twig']->render('resume.html.twig', [
|
||||
return $app['twig']->render('index.html.twig', [
|
||||
|
||||
'fullData' => $this->resumeData,
|
||||
'basics' => $this->getResumeBasics(),
|
||||
|
|
|
@ -32,14 +32,15 @@ use Symfony\Component\Validator\Constraints\NotBlank;
|
|||
class ContactType extends AbstractType
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param array $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
|
||||
$builder
|
||||
->setAction('/api/v1/message')
|
||||
->add('name', TextType::class, [
|
||||
'constraints' => [
|
||||
new Length([
|
||||
|
@ -53,7 +54,7 @@ class ContactType extends AbstractType
|
|||
],
|
||||
'label' => 'Name',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label',
|
||||
'class' => 'uk-hidden-small uk-form-label',
|
||||
],
|
||||
])
|
||||
->add('email', EmailType::class, [
|
||||
|
@ -67,7 +68,7 @@ class ContactType extends AbstractType
|
|||
],
|
||||
'label' => 'Email',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label',
|
||||
'class' => 'uk-hidden-small uk-form-label',
|
||||
],
|
||||
])
|
||||
->add('message', TextareaType::class, [
|
||||
|
@ -75,7 +76,7 @@ class ContactType extends AbstractType
|
|||
'rows' => 5,
|
||||
'cols' => 40,
|
||||
'class' => 'uk-form-large uk-width-1-1',
|
||||
'placeholder' => 'Please leave me a message, I will get back to you as soon as possible.',
|
||||
'placeholder' => 'Please leave me a message. I will get back to you as soon as possible.',
|
||||
],
|
||||
'constraints' => [
|
||||
new NotBlank(),
|
||||
|
@ -84,8 +85,9 @@ class ContactType extends AbstractType
|
|||
]),
|
||||
],
|
||||
'label_attr' => [
|
||||
'class' => 'uk-invisible uk-form-label',
|
||||
'class' => 'uk-hidden-small uk-form-label',
|
||||
],
|
||||
'label' => 'If you prefer you can send me a message at eric@ericwheeler.net',
|
||||
])
|
||||
|
||||
->add('submit', SubmitType::class, [
|
||||
|
@ -109,6 +111,7 @@ class ContactType extends AbstractType
|
|||
$resolver->setDefaults([
|
||||
'attr' => [
|
||||
'class' => 'uk-form uk-form-horizontal',
|
||||
'onsubmit' => 'return false;',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -32,5 +32,35 @@ jq(document).ready(function (jq) {
|
|||
|
||||
}
|
||||
});
|
||||
}); // Phone form
|
||||
jq('form[name=contact]').on('submit', function(event) {
|
||||
jq.post(jq(this).attr('action'), jq(this).serialize(), function(response) {
|
||||
if(response.status !== 'success') {
|
||||
jq('#' + response.id).addClass('uk-form-danger');
|
||||
UIkit.notify('<i class="uk-icon uk-icon-frown-o uk-icon-justify uk-margin-right"></i>' + response.message + ' ('+response.code+')</div>', {
|
||||
pos: 'top-center',
|
||||
status: 'danger'
|
||||
});
|
||||
console.log(response);
|
||||
} else {
|
||||
console.log(response);
|
||||
UIkit.notify('<i class="uk-icon uk-icon-check uk-icon-justify uk-margin-right"></i> ' + response.message, {
|
||||
pos: 'top-center',
|
||||
status: 'success'
|
||||
});
|
||||
var $wrapper = jq('#contact-form'),
|
||||
$button = jq('<button class="uk-modal-close uk-button uk-button-massive uk-button-primary uk-align-center" type="button">Close</button>'),
|
||||
$thankYouText = jq('<p class="uk-text-lead uk-text-center">Thank you for your message.</p><p class="uk-text-center">I will get back to you as soon as possible.</p>');
|
||||
$wrapper.empty().append($thankYouText).append($button);
|
||||
jq('a[href="#contact-form-wrapper"]').replaceWith('eric@ericwheeler.net');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
jq('form[name=contact] input, form[name=contact] textarea').on('focus', function() {
|
||||
if(jq(this).hasClass('uk-form-danger')) {
|
||||
jq(this).removeClass('uk-form-danger');
|
||||
}
|
||||
});
|
||||
});
|
|
@ -49,8 +49,17 @@ a.profile-link {
|
|||
border-bottom: 1px solid #ccc;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.uk-modal-dialog-blank {
|
||||
.uk-close {
|
||||
&:after {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.uk-button-massive {
|
||||
min-height: 64px;
|
||||
padding: 0 36px;
|
||||
line-height: 40px;
|
||||
font-size: 34px;
|
||||
border-radius: 2px;
|
||||
}
|
Loading…
Reference in New Issue