WIP: Saving Local Branch
This commit is contained in:
parent
c840954ad1
commit
e46f6e0810
|
@ -3,4 +3,15 @@ vendor/
|
|||
*~
|
||||
lib/mysql/
|
||||
composer.lock
|
||||
.idea/
|
||||
.idea/
|
||||
.php_cs.cache
|
||||
app/logs/
|
||||
build/dist/
|
||||
cache/
|
||||
html/css/
|
||||
html/images/
|
||||
html/js/
|
||||
lib/
|
||||
t.php
|
||||
test.php
|
||||
variables.less
|
||||
|
|
2
.php_cs
2
.php_cs
|
@ -33,9 +33,9 @@ return PhpCsFixer\Config::create()
|
|||
'single_import_per_statement' => false,
|
||||
'phpdoc_order' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'short_echo_tag' => false,
|
||||
'phpdoc_add_missing_param_annotation' => true,
|
||||
'psr4' => true,
|
||||
'phpdoc_var_without_name' => false,
|
||||
'no_extra_consecutive_blank_lines' => [
|
||||
'break',
|
||||
'continue',
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
|
||||
module.exports = function (grunt) {
|
||||
// Project configuration.
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %> javascript <%= grunt.template.today("yyyy-mm-dd") %> */\n',
|
||||
mangle:false
|
||||
},
|
||||
build: {
|
||||
src: 'build/dist/js/<%= pkg.name %>.js',
|
||||
dest: 'build/dist/js/<%= pkg.name %>.min.js'
|
||||
},
|
||||
vendor: {
|
||||
src: [
|
||||
'./vendor/bower/jquery/dist/jquery.js',
|
||||
'./vendor/bower/uikit/dist/js/uikit.js'
|
||||
],
|
||||
dest: 'build/dist/js/vendor.min.js'
|
||||
}
|
||||
},
|
||||
less: {
|
||||
production: {
|
||||
options: {
|
||||
compress: false,
|
||||
syncImport: true,
|
||||
plugins: [
|
||||
new (require('less-plugin-autoprefix'))({browsers: ["last 2 versions"]})
|
||||
],
|
||||
paths: [
|
||||
'vendor/bower/uikit/src/less',
|
||||
'vendor/bower/uikit/src/less/theme',
|
||||
'vendor/bower/uikit/src/less/components'
|
||||
]
|
||||
},
|
||||
files: {
|
||||
'build/dist/css/<%= pkg.name %>.css': [
|
||||
'./build/less/doughnut.less',
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
cssmin: {
|
||||
production: {
|
||||
files: [{
|
||||
expand: true,
|
||||
cwd: 'build/dist/css',
|
||||
src: ['*.css', '!*.min.css'],
|
||||
dest: 'build/dist/css',
|
||||
ext: '.min.css'
|
||||
}]
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
dev: ['Gruntfile.js', 'build/js/doughnut.js'],
|
||||
options: {
|
||||
// options here to override JSHint defaults
|
||||
reporter: require('jshint-stylish'),
|
||||
globals: {
|
||||
jQuery: true,
|
||||
console: true,
|
||||
module: true,
|
||||
document: true
|
||||
}
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
dist: {
|
||||
src: [
|
||||
'build/js/doughnut.js'
|
||||
],
|
||||
dest: 'build/dist/js/<%= pkg.name %>.js'
|
||||
}
|
||||
},
|
||||
copy: {
|
||||
main: {
|
||||
files: [
|
||||
{
|
||||
expand: true,
|
||||
cwd: 'build/dist/js',
|
||||
src: ['*.min.js'],
|
||||
dest: 'html/js',
|
||||
filter: 'isFile'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
cwd: 'build/dist/css',
|
||||
src: ['*.min.css'],
|
||||
dest: 'html/css',
|
||||
filter: 'isFile'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
cwd: './vendor/bower/uikit/dist/images',
|
||||
src: ['**'],
|
||||
dest: 'html/images'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
configFiles: {
|
||||
files: ['Gruntfile.js', 'config/*.js'],
|
||||
options: {
|
||||
reload: true
|
||||
}
|
||||
},
|
||||
less: {
|
||||
files: 'build/less/*.less',
|
||||
tasks: ['less', 'cssmin', 'copy']
|
||||
},
|
||||
js: {
|
||||
files: 'build/js/doughnut.js',
|
||||
tasks: ['concat:dist', 'jshint', 'uglify:build', 'copy']
|
||||
}
|
||||
},
|
||||
clean: [
|
||||
'build/dist',
|
||||
'html/js/*.js',
|
||||
'html/css/*.css',
|
||||
'html/images/*.svg'
|
||||
]
|
||||
});
|
||||
|
||||
// Load the plugin that provides the "uglify" task.
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-less');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
// Default task(s).
|
||||
grunt.registerTask('build', ['clean', 'concat', 'jshint', 'uglify', 'less', 'cssmin']);
|
||||
grunt.registerTask('install', ['copy']);
|
||||
grunt.registerTask('default', ['build', 'copy']);
|
||||
|
||||
|
||||
};
|
|
@ -0,0 +1,354 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Bramus\Monolog\Formatter\{
|
||||
ColorSchemes\TrafficLight,
|
||||
ColoredLineFormatter
|
||||
};
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Dflydev\Provider\DoctrineOrm\DoctrineOrmServiceProvider;
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Monolog\{
|
||||
Handler\StreamHandler,
|
||||
Logger
|
||||
};
|
||||
use Sikofitt\App\Traits\FlashTrait;
|
||||
use Silex\Application;
|
||||
use Silex\Application\{
|
||||
FormTrait,
|
||||
MonologTrait,
|
||||
SecurityTrait,
|
||||
SwiftmailerTrait,
|
||||
TranslationTrait,
|
||||
TwigTrait,
|
||||
UrlGeneratorTrait
|
||||
};
|
||||
use Silex\Provider\{
|
||||
AssetServiceProvider,
|
||||
CsrfServiceProvider,
|
||||
DoctrineServiceProvider,
|
||||
ExceptionHandlerServiceProvider,
|
||||
FormServiceProvider,
|
||||
HttpFragmentServiceProvider,
|
||||
HttpKernelServiceProvider,
|
||||
MonologServiceProvider,
|
||||
RoutingServiceProvider,
|
||||
SecurityServiceProvider,
|
||||
ServiceControllerServiceProvider,
|
||||
SessionServiceProvider,
|
||||
SwiftmailerServiceProvider,
|
||||
TwigServiceProvider,
|
||||
ValidatorServiceProvider,
|
||||
VarDumperServiceProvider,
|
||||
WebProfilerServiceProvider
|
||||
};
|
||||
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
use Symfony\Component\Debug\ExceptionHandler;
|
||||
use Symfony\Component\Form\FormFactory;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
|
||||
/**
|
||||
* Class Kernel.
|
||||
*/
|
||||
class Kernel extends Application
|
||||
{
|
||||
use FlashTrait;
|
||||
use FormTrait;
|
||||
use MonologTrait;
|
||||
use SecurityTrait;
|
||||
use SwiftmailerTrait;
|
||||
use TranslationTrait;
|
||||
use TwigTrait;
|
||||
use UrlGeneratorTrait;
|
||||
|
||||
/**
|
||||
* Kernel constructor.
|
||||
*
|
||||
* @param ClassLoader $loader
|
||||
* @param bool $debug
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(ClassLoader $loader, bool $debug = false, array $values = [])
|
||||
{
|
||||
parent::__construct($values);
|
||||
AnnotationRegistry::registerLoader([$loader, 'loadClass']);
|
||||
if (true === $debug) {
|
||||
$this->setDebug();
|
||||
}
|
||||
$this->setUpProviders();
|
||||
$this->setUpDatabase();
|
||||
$this->setUpView();
|
||||
$this->setUpLogger();
|
||||
$this->setUpMailer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $values
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function mail(array $values)
|
||||
{
|
||||
if (false === isset($values['from']) || false === is_array($values['from'])) {
|
||||
throw new \InvalidArgumentException('Array key "from" should be an array.');
|
||||
} elseif (false === isset($values['to']) || false === is_array($values['to'])) {
|
||||
throw new \InvalidArgumentException('Array key "to" should be an array.');
|
||||
} elseif (false === isset($values['body']) || false === is_string($values['body'])) {
|
||||
throw new \InvalidArgumentException('Array key "body" should be a string.');
|
||||
} elseif (false === isset($values['subject']) || false === is_string($values['subject'])) {
|
||||
throw new \InvalidArgumentException('Array key "subject" should be a string.');
|
||||
}
|
||||
|
||||
$message = \Swift_Message::newInstance();
|
||||
$message
|
||||
->setSubject($values['subject'])
|
||||
->setFrom($values['from'])
|
||||
->setTo($values['to'])
|
||||
->setBody($values['body']);
|
||||
|
||||
/**
|
||||
* @var \Swift_Transport $mailer
|
||||
*/
|
||||
$mailer = $this['mailer'];
|
||||
|
||||
return $mailer->send($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application to debug.
|
||||
*/
|
||||
public function setDebug()
|
||||
{
|
||||
$this['debug'] = true;
|
||||
ErrorHandler::register();
|
||||
ExceptionHandler::register();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getDebug(): bool
|
||||
{
|
||||
return $this['debug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseDir(): string
|
||||
{
|
||||
return __DIR__.'/..';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAppDir(): string
|
||||
{
|
||||
return $this->getBaseDir().'/app';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigDir(): string
|
||||
{
|
||||
return $this->getAppDir().'/config';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLogDir(): string
|
||||
{
|
||||
return $this->getAppDir().'/logs';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheDir(): string
|
||||
{
|
||||
return $this->getBaseDir().'/cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FormFactory
|
||||
*/
|
||||
public function getFormFactory()
|
||||
{
|
||||
return $this['form.factory'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the database environment.
|
||||
*/
|
||||
protected function setUpDatabase()
|
||||
{
|
||||
$this->register(new DoctrineServiceProvider(), [
|
||||
'db.options' => [
|
||||
'driver' => 'pdo_mysql',
|
||||
'dbname' => 'doughnut',
|
||||
'host' => 'mysql',
|
||||
'user' => 'doughnut',
|
||||
'password' => 'doughnut',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->register(new DoctrineOrmServiceProvider(), [
|
||||
'orm.proxies_dir' => $this->getCacheDir().'/doctrine/proxies',
|
||||
'orm.default_cache' => 'array',
|
||||
'orm.em.options' => [
|
||||
'connection' => 'default',
|
||||
'mappings' => [
|
||||
[
|
||||
'type' => 'annotation',
|
||||
'path' => $this->getBaseDir().'/src/Sikofitt/App/Entity',
|
||||
'namespace' => 'Sikofitt\App\Entity',
|
||||
'use_simple_annotation_reader' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the view for the application.
|
||||
*/
|
||||
protected function setUpView()
|
||||
{
|
||||
$this
|
||||
->register(new HttpKernelServiceProvider())
|
||||
->register(new RoutingServiceProvider())
|
||||
->register(new AssetServiceProvider())
|
||||
->register(new SessionServiceProvider())
|
||||
->register(new HttpFragmentServiceProvider())
|
||||
->register(new ServiceControllerServiceProvider())
|
||||
->register(new ValidatorServiceProvider());
|
||||
|
||||
$this->register(new TwigServiceProvider(), [
|
||||
'twig.path' => $this->getAppDir().'/views',
|
||||
]);
|
||||
if (true === $this['debug']) {
|
||||
$this
|
||||
->register(new VarDumperServiceProvider())
|
||||
->register(new WebProfilerServiceProvider(),
|
||||
[
|
||||
'profiler.cache_dir' => $this->getCacheDir().'/profiler',
|
||||
'profiler.mount_prefix' => '/_profiler',
|
||||
])
|
||||
->register(new ExceptionHandlerServiceProvider())
|
||||
;
|
||||
}
|
||||
/*
|
||||
* Closure supports \Twig_Environment and Silex\Application as a second
|
||||
* parameter, but we never use Silex\Application so we leave it out.
|
||||
*/
|
||||
$r = new \Symfony\Component\HttpFoundation\RequestStack();
|
||||
|
||||
$this->extend('twig', function (\Twig_Environment $twig) {
|
||||
$twig->addGlobal('session', $this['session']);
|
||||
$twig->addExtension(new TranslationExtension(new Translator('en')));
|
||||
|
||||
return $twig;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the rest of the providers for the application.
|
||||
*/
|
||||
protected function setUpProviders()
|
||||
{
|
||||
$this
|
||||
|
||||
->register(new CsrfServiceProvider())
|
||||
->register(new FormServiceProvider())
|
||||
->register(new SecurityServiceProvider(), [
|
||||
'security.firewalls' => [
|
||||
'admin' => [
|
||||
'pattern' => '^/admin',
|
||||
'http' => true,
|
||||
],
|
||||
],
|
||||
])
|
||||
;
|
||||
$this->extend('form.extensions', function ($extensions) {
|
||||
return $extensions;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the logger for the application.
|
||||
*/
|
||||
protected function setUpLogger()
|
||||
{
|
||||
if (true === $this->getDebug()) {
|
||||
$monologLevel = Logger::DEBUG;
|
||||
} else {
|
||||
$monologLevel = Logger::INFO;
|
||||
}
|
||||
$this->register(new MonologServiceProvider(), [
|
||||
'monolog.logfile' => $this->getLogDir().'/'.$this->getEnvironment().'.log',
|
||||
'monolog.level' => $monologLevel,
|
||||
]);
|
||||
$this->extend('monolog', function (Logger $monolog, Application $app) {
|
||||
$streamHandler = new StreamHandler($app['monolog.logfile']);
|
||||
$streamHandler->setFormatter(new ColoredLineFormatter(new TrafficLight()));
|
||||
$monolog->pushHandler($streamHandler);
|
||||
|
||||
return $monolog;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the mailer for the application.
|
||||
*/
|
||||
protected function setUpMailer()
|
||||
{
|
||||
$this['swiftmailer.options'] = [
|
||||
'host' => 'mx.bgemi.net',
|
||||
'port' => '25',
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
'encryption' => null,
|
||||
'auth_mode' => null,
|
||||
];
|
||||
$this->register(new SwiftmailerServiceProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getEnvironment(): string
|
||||
{
|
||||
$appEnv = getenv('APP_ENV');
|
||||
|
||||
if (false === $appEnv) {
|
||||
return 'development';
|
||||
} else {
|
||||
return $appEnv;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"report-only": false,
|
||||
"report-uri": "/csp_violation_reporting_endpoint",
|
||||
"base-uri": [],
|
||||
"default-src": {
|
||||
"self": true
|
||||
},
|
||||
"child-src": {
|
||||
"allow": [
|
||||
"https://www.youtube.com",
|
||||
"https://www.youtube-nocookie.com"
|
||||
],
|
||||
"self": false
|
||||
},
|
||||
"connect-src": {
|
||||
"self": true
|
||||
},
|
||||
"font-src": {
|
||||
"self": true,
|
||||
"data": true
|
||||
},
|
||||
"form-action": {
|
||||
"allow": [
|
||||
"http://localhost.doughnutwedding.com"
|
||||
],
|
||||
"self": true
|
||||
},
|
||||
"frame-ancestors": [],
|
||||
"img-src": {
|
||||
"self": true,
|
||||
"data": true
|
||||
},
|
||||
"media-src": [],
|
||||
"object-src": [],
|
||||
"plugin-types": [],
|
||||
"script-src": {
|
||||
"allow": [
|
||||
"https://www.google-analytics.com"
|
||||
],
|
||||
"self": true,
|
||||
"unsafe-inline": true,
|
||||
"unsafe-eval": true
|
||||
},
|
||||
"style-src": {
|
||||
"self": true,
|
||||
"unsafe-inline":true
|
||||
},
|
||||
"upgrade-insecure-requests": false
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#connections:
|
||||
# default:
|
||||
# connection:
|
||||
# driver: pdo_mysql
|
||||
# dbname: doughnut
|
||||
# password: doughnut
|
||||
# user: doughnut
|
||||
# host: mysql
|
||||
# annotation_autoloaders:
|
||||
# - 'class_exists'
|
||||
# metadata_mapping:
|
||||
# - type: 'Jgut\Slim\Doctrine\ManagerBuilder::METADATA_MAPPING_ANNOTATION'
|
||||
# path: ['__DIR__ . /../src/Sikofitt/App/Entity']
|
||||
dbs.options:
|
||||
default:
|
||||
driver: pdo_mysql
|
||||
host: mysql
|
||||
dbname: doughnut
|
||||
user: doughnut
|
||||
password: doughnut
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<meta name="viewport" id="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=10.0,initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('css/doughnutwedding.min.css') }}" />
|
||||
<script src="{{ asset('js/vendor.min.js') }}" type="text/javascript"></script>
|
||||
<script src="{{ asset('js/doughnutwedding.min.js') }}" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
{% block debug %}{% endblock %}
|
||||
|
||||
<div class="uk-container-small uk-container uk-margin-large-top uk-margin-large-bottom">
|
||||
{% include 'flash_messages.html.twig' %}
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<div class="uk-width-1-1">
|
||||
{% for messageType, messages in app.session.flashbag.all %}
|
||||
{% if messageType == 'error' %}
|
||||
{% set messageType = 'danger' %}
|
||||
{% set displayType = 'error' %}
|
||||
{% elseif messageType == 'info' %}
|
||||
{% set messageType = 'primary' %}
|
||||
{% set displayType = 'info' %}
|
||||
{% else %}
|
||||
{% set displayType = messageType %}
|
||||
{% endif %}
|
||||
<div class="uk-alert-{{ messageType }} uk-margin-small" uk-alert>
|
||||
<a class="uk-alert-close uk-text-{{ messageType }}" uk-close></a>
|
||||
<h3 class="uk-text-{{ messageType }}">{{ displayType|capitalize }}</h3>
|
||||
{% for message in messages %}
|
||||
<div class="uk-width-1-1">{{ message }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ 'Hello World!' }}
|
||||
{% for key, request in app.request_stack %}
|
||||
{{ dump(key) }}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,21 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<fieldset class="uk-fieldset uk-margin-small-bottom">
|
||||
<legend class="uk-legend">Reset Password</legend>
|
||||
</fieldset>
|
||||
<div class="uk-grid-small" uk-grid>
|
||||
<div class="uk-form-controls uk-form-controls-text uk-width-2-3@m">
|
||||
{{ form_row(form.email) }}
|
||||
</div>
|
||||
<div class="uk-form-controls uk-width-1-3@m">
|
||||
{{ form_row(form.submit) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-controls uk-form-blank">
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
|
@ -0,0 +1,5 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{% dump(request.flash) %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,70 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<fieldset class="uk-fieldset uk-margin-large-bottom">
|
||||
<legend class="uk-legend">RSVP!</legend>
|
||||
|
||||
<div class="uk-margin">
|
||||
{{ form_label(form.firstname) }}
|
||||
<div class="uk-form-controls uk-form-controls-text">
|
||||
{{ form_errors(form.firstname) }}
|
||||
{{ form_widget(form.firstname) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
{{ form_label(form.lastname) }}
|
||||
<div class="uk-form-controls uk-form-controls-text">
|
||||
{{ form_errors(form.lastname) }}
|
||||
{{ form_widget(form.lastname) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
{{ form_label(form.email) }}
|
||||
<div class="uk-form-controls uk-form-controls-text">
|
||||
{{ form_errors(form.email) }}
|
||||
{{ form_widget(form.email) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
{{ form_label(form.plainPassword) }}
|
||||
<div class="uk-form-controls uk-form-controls-text">
|
||||
{{ form_errors(form.plainPassword) }}
|
||||
{{ form_widget(form.plainPassword) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-grid-auto" uk-grid>
|
||||
<div class="uk-margin">
|
||||
{{ form_label(form.rsvp) }}
|
||||
<div class="uk-form-controls uk-form-controls-text">
|
||||
{{ form_errors(form.rsvp) }}
|
||||
{{ form_widget(form.rsvp) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<div class="uk-h4">
|
||||
({{ count }} spots available.)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
{{ form_label(form.familyside) }}
|
||||
<div class="uk-form-controls">
|
||||
{{ form_errors(form.familyside) }}
|
||||
{{ form_widget(form.familyside) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin uk-align-left@m">
|
||||
{{ form_errors(form.family) }}
|
||||
{{ form_label(form.family) }}
|
||||
{{ form_widget(form.family) }}
|
||||
|
||||
</div>
|
||||
<div class="uk-margin uk-align-right@m">
|
||||
<input type="submit" class="uk-button-primary uk-button uk-button" value="Save" />
|
||||
</div>
|
||||
</fieldset>
|
||||
{{ form_rest(form) }}
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
|
@ -0,0 +1,3 @@
|
|||
jQuery.ready(function($) {
|
||||
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
@import "../../vendor/bower/uikit/src/less/uikit.less";
|
||||
@import "../../vendor/bower/uikit/src/less/components/variables.less";
|
||||
|
||||
//@global-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
//@global-font-size: 16px;
|
||||
|
||||
@form-background: #ffffff;
|
||||
|
||||
.uk-input,
|
||||
.uk-select,
|
||||
.uk-textarea {
|
||||
border:1px solid @global-muted-background;
|
||||
background: #ffffff;
|
||||
}
|
||||
.uk-input:focus,
|
||||
.uk-select:focus,
|
||||
.uk-textarea:focus {
|
||||
background: #f5fbfe;
|
||||
border:1px solid #99baca;
|
||||
color: #666;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
|
||||
use Doctrine\DBAL\Tools\Console\ConsoleRunner;
|
||||
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
|
||||
/**
|
||||
* @var EntityManager $em
|
||||
*/
|
||||
$em = require 'doctrine.php';
|
||||
|
||||
$helperSet = new HelperSet([
|
||||
'db' => new ConnectionHelper($em->getConnection()),
|
||||
'em' => new EntityManagerHelper($em),
|
||||
|
||||
]);
|
||||
|
||||
return $helperSet;
|
|
@ -3,32 +3,57 @@
|
|||
"description": "doughnutwedding.com website",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"hoa/router": "3.17.01.14",
|
||||
"twig/twig": "^2.1",
|
||||
"twig/extensions": "^1.4",
|
||||
"php":">=7.0",
|
||||
"bramus/monolog-colored-line-formatter": "~2.0",
|
||||
"container-interop/container-interop": "^1.1",
|
||||
"dflydev/doctrine-orm-service-provider": "^2.0",
|
||||
"doctrine/annotations": "^1.3",
|
||||
"doctrine/collections": "^1.4",
|
||||
"doctrine/dbal": "^2.5",
|
||||
"doctrine/orm": "^2.5",
|
||||
"symfony/console": "^3.2",
|
||||
"pimple/pimple": "^3.0",
|
||||
"symfony/http-foundation": "^3.2",
|
||||
"symfony/config": "^3.2",
|
||||
"symfony/yaml": "^3.2",
|
||||
"doctrine/annotations": "^1.3",
|
||||
"tedivm/stash": "^0.14.1",
|
||||
"doctrine/collections": "^1.4",
|
||||
"ircmaxell/security-lib": "^1.1",
|
||||
"egulias/email-validator": "^2.1",
|
||||
"google/recaptcha": "^1.1",
|
||||
"ircmaxell/random-lib": "^1.2",
|
||||
"sikofitt/retrorsum": "^1.0"
|
||||
"ircmaxell/security-lib": "^1.1",
|
||||
"monolog/monolog": "^1.22",
|
||||
"paragonie/cookie": "^3.1",
|
||||
"paragonie/csp-builder": "^2.0",
|
||||
"paragonie/sodium_compat": "^0.4.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/log": "^1.0",
|
||||
"silex/silex": "^2.0",
|
||||
"swiftmailer/swiftmailer": "^5.4",
|
||||
"symfony/asset": "^3.2",
|
||||
"symfony/config": "^3.2",
|
||||
"symfony/console": "^3.2",
|
||||
"symfony/form": "^3.2",
|
||||
"symfony/http-foundation": "^3.2",
|
||||
"symfony/monolog-bridge": "^3.2",
|
||||
"symfony/security-csrf": "^3.2",
|
||||
"symfony/security-guard": "^3.2",
|
||||
"symfony/security-http": "^3.2",
|
||||
"symfony/twig-bridge": "^3.2",
|
||||
"symfony/validator": "^3.2",
|
||||
"symfony/yaml": "^3.2",
|
||||
"tedivm/stash": "^0.14.1",
|
||||
"twig/extensions": "^1.4",
|
||||
"twig/twig": "^2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.0",
|
||||
"fzaninotto/faker": "^1.6",
|
||||
"friendsofphp/php-cs-fixer": "^2.0"
|
||||
"phpunit/phpunit": "^6.0",
|
||||
"silex/providers": "^2.0",
|
||||
"silex/web-profiler": "^2.0",
|
||||
"symfony/debug-bundle": "^3.2",
|
||||
"symfony/var-dumper": "^3.2"
|
||||
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"psr-4": {
|
||||
"Sikofitt\\":"src/Sikofitt"
|
||||
}
|
||||
},
|
||||
"files": ["app/Kernel.php"]
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
|
@ -37,5 +62,8 @@
|
|||
"email": "sikofitt@gmail.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable"
|
||||
"minimum-stability": "stable",
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,16 @@ services:
|
|||
- php
|
||||
- mysql
|
||||
restart: always
|
||||
environment:
|
||||
- "APP_ENV=development"
|
||||
php:
|
||||
build: ./docker/php
|
||||
volumes:
|
||||
- ./:/var/www
|
||||
- ./html:/var/www/html
|
||||
restart: always
|
||||
environment:
|
||||
- "APP_ENV=development"
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
|
|
|
@ -16,6 +16,8 @@ RUN apk update && apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && apk a
|
|||
|
||||
RUN /usr/local/bin/docker-php-ext-install pdo_mysql intl
|
||||
|
||||
RUN echo "y\n"|pecl install scrypt && /usr/local/bin/docker-php-ext-enable scrypt
|
||||
RUN echo "y\n"|pecl install xdebug && /usr/local/bin/docker-php-ext-enable xdebug
|
||||
RUN apk del .build-deps
|
||||
|
||||
COPY ./php.ini /usr/local/etc/php
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use Jgut\Slim\Doctrine\ManagerBuilder;
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
$settings = [
|
||||
'default' => [
|
||||
'annotation_autoloaders' => ['class_exists'],
|
||||
'connection' => [
|
||||
'driver' => 'pdo_mysql',
|
||||
'user' => 'doughnut',
|
||||
'password' => 'doughnut',
|
||||
'dbname' => 'doughnut',
|
||||
'host' => 'mysql',
|
||||
],
|
||||
'metadata_mapping' => [
|
||||
[
|
||||
'type' => ManagerBuilder::METADATA_MAPPING_ANNOTATION,
|
||||
'path' => [__DIR__ . '/src/Sikofitt/App/Entity'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$managerBuilder = new ManagerBuilder([ManagerBuilder::RELATIONAL_MANAGER_KEY => 'default']);
|
||||
$managerBuilder->loadSettings($settings);
|
||||
return $managerBuilder->getManager('entityManager');
|
||||
|
||||
|
||||
|
|
@ -18,4 +18,38 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
phpinfo();
|
||||
use Sikofitt\App\Controller\DefaultController;
|
||||
use Sikofitt\App\Controller\RsvpController;
|
||||
use Sikofitt\App\Middleware\CspMiddleware;
|
||||
use Sikofitt\App\Middleware\HeaderMiddleware;
|
||||
|
||||
$loader = require __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$app = new Kernel($loader, true);
|
||||
// Controllers
|
||||
// Default
|
||||
$app->get('/', DefaultController::class.'::indexAction')
|
||||
->bind('index');
|
||||
//$app->match('/login', DefaultController::class.'loginAction')
|
||||
// ->bind('login');
|
||||
// RSVP Actions
|
||||
$app->match('/rsvp', RsvpController::class.'::indexAction')
|
||||
->method('GET|POST')
|
||||
->bind('rsvp');
|
||||
$app->match('/rsvp/reset', RsvpController::class.'::resetAction')
|
||||
->method('GET|POST')
|
||||
->bind('rsvp_password_reset');
|
||||
$app->get('/rsvp/reset/{token}', RsvpController::class.'::tokenAction')
|
||||
->bind('rsvp_token');
|
||||
|
||||
//->before(new MysqlAuthenticatorMiddleware());
|
||||
$app->match('/rsvp/edit', RsvpController::class.'::editAction')
|
||||
->method('GET|POST')
|
||||
->bind('rsvp_edit');
|
||||
//->before(new MysqlAuthenticatorMiddleware());
|
||||
// Middleware
|
||||
$app->before(new CspMiddleware(), \Kernel::EARLY_EVENT);
|
||||
|
||||
$app->before(new HeaderMiddleware(), \Kernel::EARLY_EVENT);
|
||||
// Run the app
|
||||
$app->run();
|
||||
|
|
|
@ -17,9 +17,15 @@
|
|||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-contrib-clean": "^1.0.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"grunt-contrib-cssmin": "^1.0.2",
|
||||
"grunt-contrib-jshint": "^1.1.0",
|
||||
"grunt-contrib-less": "^1.4.0",
|
||||
"grunt-contrib-uglify": "^2.1.0",
|
||||
"grunt-contrib-watch": "^1.0.0",
|
||||
"jshint-stylish": "^2.2.1",
|
||||
"less-plugin-autoprefix": "^1.5.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Configuration;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
|
||||
class DatabaseConfiguration implements ConfigurationInterface
|
||||
{
|
||||
public function getConfigTreeBuilder()
|
||||
{
|
||||
$treeBuilder = new TreeBuilder();
|
||||
$rootNode = $treeBuilder->root('doughnut');
|
||||
|
||||
$rootNode->children()
|
||||
->arrayNode('connections')
|
||||
->prototype('array')
|
||||
->children()
|
||||
->arrayNode('connection')
|
||||
->children()
|
||||
->scalarNode('driver')
|
||||
->isRequired()
|
||||
->validate()
|
||||
->ifNotInArray(['pdo_mysql', 'pdo_pgsql', 'pdo_sqlite'])
|
||||
->thenInvalid('Invalid driver : %s')
|
||||
->end() // ifNotInArray
|
||||
->end() // driver
|
||||
->scalarNode('dbname')->isRequired()->end() // database
|
||||
->scalarNode('host')->defaultValue('127.0.0.1')->end()
|
||||
->scalarNode('user')->isRequired()->end()
|
||||
->scalarNode('password')->isRequired()->end()
|
||||
->end() // connection.prototype
|
||||
->end() // connection
|
||||
->arrayNode('annotation_autoloaders')
|
||||
->requiresAtLeastOneElement()
|
||||
->prototype('scalar')
|
||||
->isRequired()
|
||||
->end()
|
||||
->end()
|
||||
->arrayNode('metadata_mapping')
|
||||
->prototype('array')
|
||||
->children()
|
||||
->arrayNode('path')
|
||||
->requiresAtLeastOneElement()
|
||||
->prototype('scalar')
|
||||
->isRequired()
|
||||
->end()
|
||||
->end()
|
||||
->scalarNode('type')
|
||||
->isRequired()
|
||||
->beforeNormalization()
|
||||
->ifString()
|
||||
->then(function ($s) {
|
||||
return $this->normalizeConstant($s);
|
||||
})
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end();
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
|
||||
private function normalizeConstant($const)
|
||||
{
|
||||
$classParts = explode('::', $const);
|
||||
if (isset($classParts[1])) {
|
||||
$reflected = new \ReflectionClass($classParts[0]);
|
||||
$constant = $reflected->getConstant($classParts[1]);
|
||||
|
||||
return $constant;
|
||||
} else {
|
||||
return $const;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Controller;
|
||||
|
||||
use Sikofitt\App\Form\RsvpType;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
|
||||
use Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension;
|
||||
use Symfony\Component\Form\Forms;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Csrf\CsrfTokenManager;
|
||||
|
||||
class DefaultController
|
||||
{
|
||||
public function indexAction(Request $request, \Kernel $app)
|
||||
{
|
||||
return $app->render('index.html.twig', ['request' => $request]);
|
||||
}
|
||||
|
||||
public function rsvpAction()
|
||||
{
|
||||
/* $app = $this->app;
|
||||
$rsvp = new Rsvp();
|
||||
$rsvp
|
||||
->setGuests(2)
|
||||
->setCreated(new \DateTime('now'))
|
||||
->setUpdated(new \DateTime('now'));
|
||||
|
||||
$user = new User();
|
||||
$user->setFirstName('Eric')
|
||||
->setLastName('Wheeler')
|
||||
->setFamily(true)
|
||||
->setEmail('sikofitt@gmail.com')
|
||||
->setCreated(new \DateTime('now'))
|
||||
->setUpdated(new \DateTime('now'))
|
||||
->setFamilySide(User::ERIC_SIDE)
|
||||
->setRsvp($rsvp);
|
||||
|
||||
|
||||
$app['em']->persist($user);
|
||||
$app['em']->flush(); */
|
||||
$bytes = \ParagonIE_Sodium_Compat::randombytes_buf(22);
|
||||
|
||||
$password = new Password(new ScryptPassword());
|
||||
// dump($password->hash('password'));
|
||||
$blake = \ParagonIE_Sodium_Compat::crypto_generichash($bytes);
|
||||
$blake2b = \ParagonIE_Sodium_Core_BLAKE2b::bin2hex($blake);
|
||||
|
||||
$formFactory = Forms::createFormFactoryBuilder()
|
||||
->addTypeExtension(new FormTypeHttpFoundationExtension())
|
||||
->addExtension(new CsrfExtension(new CsrfTokenManager()))
|
||||
->getFormFactory();
|
||||
$form = $formFactory->create(RsvpType::class);
|
||||
// dump($form->createView());
|
||||
return 'hello';
|
||||
//return $this->container->get('view')->render('RsvpForm.html.twig', ['form' => $form->createView()]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Sikofitt\{
|
||||
App\Entity\Rsvp, App\Entity\User, App\Form\ResetType, App\Form\RsvpType, App\Repository\RsvpRepository, App\Repository\UserRepository
|
||||
};
|
||||
|
||||
use Symfony\Component\Form\FormFactory;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
|
||||
class RsvpController
|
||||
{
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* @param \Kernel $app
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction(Request $request, \Kernel $app)
|
||||
{
|
||||
/**
|
||||
* @var EntityManager $em
|
||||
* @var RsvpRepository $rsvpRepo
|
||||
* @var UserRepository $userRepo
|
||||
*/
|
||||
$em = $app['orm.em'];
|
||||
$rsvpRepo = $em->getRepository('Sikofitt\App\Entity\Rsvp');
|
||||
$count = (40 - $rsvpRepo->getRsvpCount());
|
||||
$userRepo = $em->getRepository('Sikofitt\App\Entity\User');
|
||||
$kCount = $userRepo->getKatrinaCount();
|
||||
$eCount = $userRepo->getEricCount();
|
||||
/**
|
||||
* @var FormFactory $formFactory
|
||||
*/
|
||||
$formFactory = $app['form.factory'];
|
||||
$user = new User();
|
||||
$rsvp = new Rsvp();
|
||||
$rsvp
|
||||
->setCreated(new \DateTime('now'))
|
||||
->setUpdated(new \DateTime('now'));
|
||||
$user
|
||||
->setRsvp($rsvp)
|
||||
->setCreated(new \DateTime('now'))
|
||||
->setUpdated(new \DateTime('now'));
|
||||
|
||||
$form = $formFactory->create(RsvpType::class, $user);
|
||||
if ($request->isMethod('POST')) {
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$user = $form->getData();
|
||||
$user->setPassword($user->getPlainPassword());
|
||||
/**
|
||||
* @var EntityManager $em
|
||||
*/
|
||||
$em = $app['orm.em'];
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
return $app->redirect('/rsvp');
|
||||
}
|
||||
}
|
||||
|
||||
return $app->render(
|
||||
'rsvp_form.html.twig',
|
||||
[
|
||||
'form' => $form->createView(),
|
||||
'count' => $count,
|
||||
'kCount' => $kCount,
|
||||
'eCount' => $eCount,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* @param \Kernel $app
|
||||
* @param string $token
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function resetAction(Request $request, \Kernel $app)
|
||||
{
|
||||
$formFactory = $app->getFormFactory();
|
||||
$passwordResetForm = $formFactory
|
||||
->createBuilder(ResetType::class)
|
||||
->getForm();
|
||||
$update = false;
|
||||
if ($request->isMethod('POST')) {
|
||||
$passwordResetForm->handleRequest($request);
|
||||
if ($passwordResetForm->isSubmitted() && $passwordResetForm->isValid()) {
|
||||
$data = $passwordResetForm->get('email')->getData();
|
||||
$update = $app['orm.em']->getRepository('Sikofitt\App\Entity\User')
|
||||
->setResetToken($data);
|
||||
} else {
|
||||
$data = null;
|
||||
}
|
||||
} else {
|
||||
$data = null;
|
||||
}
|
||||
/**
|
||||
* @var UserRepository $userRepo
|
||||
*/
|
||||
$userRepo = $app['orm.em']->getRepository('Sikofitt\App\Entity\User');
|
||||
|
||||
//$emailResult = $userRepo->getEmail($passwordResetForm->get('email'));
|
||||
/*if(null === $emailResult) {
|
||||
return $app->render('reset_password_confirm.html.twig', [
|
||||
'message' => 'Email was not found in database',
|
||||
]);
|
||||
} elseif($emailResult instanceof ConstraintViolationList) {
|
||||
return $app->render(
|
||||
'reset_password.html.twig',
|
||||
[
|
||||
'form' => $passwordResetForm->createView(),
|
||||
'data' => $data,
|
||||
'email' => $emailResult,
|
||||
'message' => $emailResult,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
return $app->render('reset_password_confirm.html.twig', [
|
||||
'message' => 'Please check your email. A reset request has been sent.',
|
||||
]);
|
||||
}*/
|
||||
$app->addInfo('Message', 'message 2');
|
||||
return $app->render(
|
||||
'reset_password.html.twig',
|
||||
[
|
||||
'form' => $passwordResetForm->createView(),
|
||||
'data' => $data,
|
||||
//'email' => $emailResult,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function tokenAction(Request $request, \Kernel $app, string $token = null)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Class Rsvp.
|
||||
*
|
||||
* @ORM\Table(name="rsvps")
|
||||
* @ORM\Entity(repositoryClass="Sikofitt\App\Repository\RsvpRepository")
|
||||
*/
|
||||
class Rsvp
|
||||
{
|
||||
/**
|
||||
* @var int $id
|
||||
* @ORM\Id()
|
||||
* @ORM\Column(name="id", type="integer", unique=true, nullable=false)
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
* @Assert\NotBlank()
|
||||
* @Assert\Regex(pattern="'/\d+/'")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @ORM\OneToOne(targetEntity="Sikofitt\App\Entity\User", mappedBy="rsvp", cascade={"persist"})
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @ORM\Column(name="guests", nullable=true, type="integer")
|
||||
* @Assert\Regex(pattern="'/\d+/'")
|
||||
* @Assert\Range(min="1", max="2")
|
||||
*/
|
||||
private $guests;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="created", type="datetime")
|
||||
*/
|
||||
private $created = null;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="updated", type="datetime")
|
||||
*/
|
||||
private $updated = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (null === $this->created) {
|
||||
$this->created = new \DateTime('now');
|
||||
}
|
||||
$this->updated = new \DateTime('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set guests.
|
||||
*
|
||||
* @param int $guests
|
||||
*
|
||||
* @return Rsvp
|
||||
*/
|
||||
public function setGuests($guests)
|
||||
{
|
||||
$this->guests = $guests;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get guests.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getGuests()
|
||||
{
|
||||
return $this->guests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set created.
|
||||
*
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return Rsvp
|
||||
*/
|
||||
public function setCreated($created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get created.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set updated.
|
||||
*
|
||||
* @param \DateTime $updated
|
||||
*
|
||||
* @return Rsvp
|
||||
*/
|
||||
public function setUpdated($updated)
|
||||
{
|
||||
$this->updated = $updated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updated.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdated()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user.
|
||||
*
|
||||
* @param \Sikofitt\App\Entity\User $user
|
||||
*
|
||||
* @return Rsvp
|
||||
*/
|
||||
public function setUser(\Sikofitt\App\Entity\User $user = null)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user.
|
||||
*
|
||||
* @return \Sikofitt\App\Entity\User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,390 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Class User.
|
||||
*
|
||||
* @ORM\Entity(repositoryClass="Sikofitt\App\Repository\UserRepository")
|
||||
* @ORM\Table(name="users")
|
||||
*/
|
||||
class User
|
||||
{
|
||||
const KATRINA_SIDE = 'Katrina';
|
||||
|
||||
const ERIC_SIDE = 'Eric';
|
||||
|
||||
/**
|
||||
* @ORM\Id()
|
||||
* @ORM\Column(name="id", type="integer", nullable=false, unique=true)
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="first_name", type="string", length=255, nullable=false)
|
||||
* @Assert\NotBlank()
|
||||
* @Assert\Regex(pattern="/\w+/")
|
||||
*/
|
||||
private $firstName;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="last_name", type="string", length=255, nullable=false)
|
||||
* @Assert\NotBlank()
|
||||
* @Assert\Regex(pattern="/\w+/")
|
||||
*/
|
||||
private $lastName;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", name="is_family", nullable=false)
|
||||
* @Assert\Type(type="bool")
|
||||
*/
|
||||
private $family = false;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", name="family_side", nullable=true)
|
||||
* @Assert\Choice(choices="{self::KATRINA_SIDE, self::ERIC_SIDE}", multiple=false)
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
private $familySide = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="email", type="string", length=255)
|
||||
* @Assert\Email(strict=true, checkHost=true, checkMX=true)
|
||||
*/
|
||||
private $email;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="password", type="string", length=255))
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $plainPassword;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="token", type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $token;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @ORM\OneToOne(targetEntity="Sikofitt\App\Entity\Rsvp", inversedBy="user", cascade={"persist"})
|
||||
*/
|
||||
private $rsvp;
|
||||
/**
|
||||
* @ORM\Column(type="datetime", name="created")
|
||||
*/
|
||||
private $created = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime", name="updated")
|
||||
*/
|
||||
private $updated = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (null === $this->created) {
|
||||
$this->created = new \DateTime('now');
|
||||
}
|
||||
$this->updated = new \DateTime('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set firstName.
|
||||
*
|
||||
* @param string $firstName
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setFirstName($firstName)
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get firstName.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstName()
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastName.
|
||||
*
|
||||
* @param string $lastName
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setLastName($lastName)
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastName.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLastName()
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set family.
|
||||
*
|
||||
* @param bool $family
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setFamily($family)
|
||||
{
|
||||
$this->family = $family;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get family.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getFamily()
|
||||
{
|
||||
return $this->family;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set familySide.
|
||||
*
|
||||
* @param string $familySide
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setFamilySide($familySide)
|
||||
{
|
||||
$this->familySide = $familySide;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get familySide.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFamilySide()
|
||||
{
|
||||
return $this->familySide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set email.
|
||||
*
|
||||
* @param string $email
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get email.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $password
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$encoder = new BCryptPasswordEncoder(14);
|
||||
|
||||
$salt = bin2hex(random_bytes(16));
|
||||
$this->password = $encoder->encodePassword($password, $salt);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPlainPassword(): string
|
||||
{
|
||||
if (null === $this->plainPassword) {
|
||||
return '';
|
||||
} else {
|
||||
return $this->plainPassword;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plainPassword
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setPlainPassword(string $plainPassword): User
|
||||
{
|
||||
$this->plainPassword = $plainPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setToken($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set created.
|
||||
*
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setCreated($created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get created.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set updated.
|
||||
*
|
||||
* @param \DateTime $updated
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setUpdated($updated)
|
||||
{
|
||||
$this->updated = $updated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updated.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdated()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rsvp.
|
||||
*
|
||||
* @param \Sikofitt\App\Entity\Rsvp $rsvp
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setRsvp(\Sikofitt\App\Entity\Rsvp $rsvp = null)
|
||||
{
|
||||
$this->rsvp = $rsvp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rsvp.
|
||||
*
|
||||
* @return \Sikofitt\App\Entity\Rsvp
|
||||
*/
|
||||
public function getRsvp()
|
||||
{
|
||||
return $this->rsvp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Validator\Constraints\Email;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
|
||||
/**
|
||||
* Class ResetType.
|
||||
*/
|
||||
class ResetType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @param \Symfony\Component\Form\FormBuilderInterface $builder
|
||||
* @param array $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('email', EmailType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-input uk-form-large uk-padding-small uk-box-shadow-hover-small',
|
||||
'placeholder' => 'Email address',
|
||||
],
|
||||
'label' => 'Email address',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary uk-hidden',
|
||||
],
|
||||
'constraints' => [
|
||||
new NotBlank(),
|
||||
new Email([
|
||||
'strict' => true,
|
||||
'checkMX' => true,
|
||||
'checkHost' => true,
|
||||
]),
|
||||
],
|
||||
])
|
||||
->add('submit', SubmitType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-button uk-button-large uk-button-primary uk-width-1-1@s',
|
||||
],
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefault('attr', [
|
||||
'class' => 'uk-form uk-margin-large',
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Form;
|
||||
|
||||
use Sikofitt\App\Entity\Rsvp;
|
||||
use Sikofitt\App\Entity\User;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\Type\{
|
||||
CheckboxType,
|
||||
ChoiceType,
|
||||
EmailType,
|
||||
IntegerType,
|
||||
PasswordType,
|
||||
RadioType,
|
||||
TextType
|
||||
};
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class RsvpType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('firstname', TextType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-input uk-form-large uk-padding-small uk-box-shadow-hover-small',
|
||||
'placeholder' => 'First Name',
|
||||
],
|
||||
'label' => 'First name',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary',
|
||||
],
|
||||
])
|
||||
->add('lastname', TextType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-input uk-form-large uk-padding-small uk-box-shadow-hover-small',
|
||||
'placeholder' => 'Last Name',
|
||||
],
|
||||
'label' => 'Last name',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary',
|
||||
],
|
||||
])
|
||||
->add('email', EmailType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-input uk-form-large uk-padding-small uk-box-shadow-hover-small',
|
||||
'placeholder' => 'Email address',
|
||||
],
|
||||
'label' => 'Email address',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary',
|
||||
],
|
||||
])
|
||||
->add('plainPassword', PasswordType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-input uk-form-large uk-padding-small uk-box-shadow-hover-small',
|
||||
'placeholder' => 'Password',
|
||||
],
|
||||
'label' => 'Password',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary',
|
||||
],
|
||||
])
|
||||
->add('rsvp', IntegerType::class, [
|
||||
'attr' => [
|
||||
'class' => 'uk-input uk-form-large uk-padding-small uk-form-width-medium uk-box-shadow-hover-small',
|
||||
'placeholder' => 'Number of Guests (including yourself)',
|
||||
],
|
||||
'label' => 'Number of guests? (including yourself)',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary',
|
||||
],
|
||||
])
|
||||
->add('familyside', ChoiceType::class, [
|
||||
'choices' => [
|
||||
User::ERIC_SIDE => User::ERIC_SIDE,
|
||||
User::KATRINA_SIDE => User::KATRINA_SIDE,
|
||||
],
|
||||
'attr' => [
|
||||
'class' => 'uk-select uk-form-large uk-box-shadow-hover-small',
|
||||
'style' => 'padding-left:16px;',
|
||||
],
|
||||
'label' => 'Who are you coming for?',
|
||||
'label_attr' => [
|
||||
'class' => 'uk-form-label uk-text-primary',
|
||||
],
|
||||
])
|
||||
->add('family', CheckboxType::class, [
|
||||
'label' => 'Are you an immediate family member?',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
'class' => 'uk-checkbox uk-box-shadow-hover-small',
|
||||
],
|
||||
'label_attr' => [
|
||||
'class' => 'uk-margin-right',
|
||||
],
|
||||
]);
|
||||
$builder->get('rsvp')
|
||||
->addModelTransformer(new CallbackTransformer(
|
||||
function ($rsvp) {
|
||||
if (null === $rsvp) {
|
||||
return $rsvp;
|
||||
} else {
|
||||
return $rsvp->getGuests();
|
||||
}
|
||||
},
|
||||
function (Int $rsvpInt) {
|
||||
$rsvp = new Rsvp();
|
||||
$rsvp->setGuests($rsvpInt);
|
||||
|
||||
return $rsvp;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefault('data_class', User::class);
|
||||
$resolver->setDefault('attr', ['class' => 'uk-form-horizontal uk-margin-large']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Middleware;
|
||||
|
||||
use Monolog\Logger;
|
||||
use ParagonIE\CSPBuilder\CSPBuilder;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Class CspMiddleware.
|
||||
*
|
||||
* Builds Content Security Policy (CSP) headers.
|
||||
*/
|
||||
class CspMiddleware
|
||||
{
|
||||
public function __invoke(Request $request, \Kernel $app)
|
||||
{
|
||||
$cspDir = realpath($app->getConfigDir());
|
||||
if (false === file_exists($cspDir.'/csp.json')) {
|
||||
$app->log(
|
||||
sprintf('csp.json was not found in %s, skipping.', $cspDir),
|
||||
[
|
||||
'configured log dir' => realpath($cspDir),
|
||||
],
|
||||
Logger::NOTICE
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
$app->log('Setting Content Security Policy (CSP) headers.',
|
||||
[
|
||||
'class' => get_class($this),
|
||||
]
|
||||
);
|
||||
$csp = CSPBuilder::fromFile($app->getBaseDir().'/app/config/csp.json');
|
||||
$csp->sendCSPHeader();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Middleware;
|
||||
|
||||
use Silex\Application;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Class HeaderMiddleware.
|
||||
*
|
||||
* Injects custom headers into the application.
|
||||
*/
|
||||
class HeaderMiddleware
|
||||
{
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* @param \Silex\Application $app
|
||||
*/
|
||||
public function __invoke(Request $request, Application $app)
|
||||
{
|
||||
$poweredByLine = sprintf('Silex/%s [%s] %s/%s', Application::VERSION, php_sapi_name(), php_uname('s'), php_uname('m'));
|
||||
|
||||
header('X-Powered-By: '.$poweredByLine);
|
||||
header('Server: Nginx/Unix ('.php_uname('m').')');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
class RsvpRepository extends EntityRepository
|
||||
{
|
||||
public function getRsvpCount()
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
->select('sum(r.guests)')
|
||||
->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Sikofitt\App\Entity\User;
|
||||
use Symfony\Component\Validator\Constraints\Email;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
|
||||
/**
|
||||
* Class UserRepository.
|
||||
*
|
||||
* Doctrine repository for User entity.
|
||||
*/
|
||||
class UserRepository extends EntityRepository
|
||||
{
|
||||
public function getKatrinaCount()
|
||||
{
|
||||
return $this->createQueryBuilder('u')
|
||||
->select('count(u.familySide)')
|
||||
->distinct(true)
|
||||
->where('u.familySide = :side')
|
||||
->setParameter('side', User::KATRINA_SIDE)
|
||||
->getQuery()
|
||||
->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
|
||||
}
|
||||
|
||||
public function getEricCount()
|
||||
{
|
||||
return $this->createQueryBuilder('u')
|
||||
->select('count(u.familySide)')
|
||||
->distinct(true)
|
||||
->where('u.familySide = :side')
|
||||
->setParameter('side', User::ERIC_SIDE)
|
||||
->getQuery()
|
||||
->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
|
||||
}
|
||||
|
||||
public function getEmail(string $email)
|
||||
{
|
||||
$validator = Validation::createValidator();
|
||||
$emailConstraint = new Email([
|
||||
'checkMX' => true,
|
||||
'checkHost' => true,
|
||||
'strict' => true,
|
||||
]);
|
||||
|
||||
$result = $validator->validate($email, [$emailConstraint]);
|
||||
|
||||
if ($result->count() > 0) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $this->createQueryBuilder('u')
|
||||
->select('u.email')
|
||||
->where('u.email = :email')
|
||||
->setParameter('email', $email)
|
||||
->getQuery()
|
||||
->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
|
||||
}
|
||||
|
||||
public function setResetToken(string $email)
|
||||
{
|
||||
$token = bin2hex(random_bytes(22));
|
||||
|
||||
return (bool) $this->createQueryBuilder('u')
|
||||
->update()
|
||||
->set('u.token', ':token')
|
||||
->setParameter('token', $token)
|
||||
->where('u.email = :email')
|
||||
->setParameter('email', $email)
|
||||
->getQuery()
|
||||
->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\App\Traits;
|
||||
|
||||
/**
|
||||
* Trait FlashTrait.
|
||||
*
|
||||
* Adds shortcuts for adding flash messages.
|
||||
*/
|
||||
trait FlashTrait
|
||||
{
|
||||
/**
|
||||
* @param \string[] ...$messages
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addInfo(string ...$messages)
|
||||
{
|
||||
if (false === isset($this['session'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this['session']->getFlashBag()->add('info', $message);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \string[] ...$messages
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addError(string ...$messages)
|
||||
{
|
||||
if (false === isset($this['session'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this['session']->getFlashBag()->add('error', $message);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \string[] ...$messages
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addSuccess(string ...$messages)
|
||||
{
|
||||
if (false === isset($this['session'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this['session']->getFlashBag()->add('success', $message);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addWarning(string ...$messages)
|
||||
{
|
||||
if (false === isset($this['session'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this['session']->getFlashBag()->add('warning', $message);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\Security;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
|
||||
|
||||
class MysqlAuthenticator extends AbstractGuardAuthenticator
|
||||
{
|
||||
/**
|
||||
* Returns a response that directs the user to authenticate.
|
||||
*
|
||||
* This is called when an anonymous request accesses a resource that
|
||||
* requires authentication. The job of this method is to return some
|
||||
* response that "helps" the user start into the authentication process.
|
||||
*
|
||||
* Examples:
|
||||
* A) For a form login, you might redirect to the login page
|
||||
* return new RedirectResponse('/login');
|
||||
* B) For an API token authentication system, you return a 401 response
|
||||
* return new Response('Auth header required', 401);
|
||||
*
|
||||
* @param Request $request The request that resulted
|
||||
* in an
|
||||
* AuthenticationException
|
||||
* @param AuthenticationException $authException The exception that started
|
||||
* the authentication process
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function start(
|
||||
Request $request,
|
||||
AuthenticationException $authException = null
|
||||
) {
|
||||
// TODO: Implement start() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication credentials from the request and return them
|
||||
* as any type (e.g. an associate array). If you return null,
|
||||
* authentication
|
||||
* will be skipped.
|
||||
*
|
||||
* Whatever value you return here will be passed to getUser() and
|
||||
* checkCredentials()
|
||||
*
|
||||
* For example, for a form login, you might:
|
||||
*
|
||||
* if ($request->request->has('_username')) {
|
||||
* return array(
|
||||
* 'username' => $request->request->get('_username'),
|
||||
* 'password' => $request->request->get('_password'),
|
||||
* );
|
||||
* } else {
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* Or for an API token that's on a header, you might use:
|
||||
*
|
||||
* return array('api_key' => $request->headers->get('X-API-TOKEN'));
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getCredentials(Request $request)
|
||||
{
|
||||
// TODO: Implement getCredentials() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a UserInterface object based on the credentials.
|
||||
*
|
||||
* The *credentials* are the return value from getCredentials()
|
||||
*
|
||||
* You may throw an AuthenticationException if you wish. If you return
|
||||
* null, then a UsernameNotFoundException is thrown for you.
|
||||
*
|
||||
* @param mixed $credentials
|
||||
* @param UserProviderInterface $userProvider
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
*
|
||||
* @return UserInterface|null
|
||||
*/
|
||||
public function getUser($credentials, UserProviderInterface $userProvider)
|
||||
{
|
||||
// TODO: Implement getUser() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the credentials are valid.
|
||||
*
|
||||
* If any value other than true is returned, authentication will
|
||||
* fail. You may also throw an AuthenticationException if you wish
|
||||
* to cause authentication to fail.
|
||||
*
|
||||
* The *credentials* are the return value from getCredentials()
|
||||
*
|
||||
* @param mixed $credentials
|
||||
* @param UserInterface $user
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkCredentials($credentials, UserInterface $user)
|
||||
{
|
||||
// TODO: Implement checkCredentials() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when authentication executed, but failed (e.g. wrong username
|
||||
* password).
|
||||
*
|
||||
* This should return the Response sent back to the user, like a
|
||||
* RedirectResponse to the login page or a 403 response.
|
||||
*
|
||||
* If you return null, the request will continue, but the user will
|
||||
* not be authenticated. This is probably not what you want to do.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param AuthenticationException $exception
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
public function onAuthenticationFailure(
|
||||
Request $request,
|
||||
AuthenticationException $exception
|
||||
) {
|
||||
// TODO: Implement onAuthenticationFailure() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when authentication executed and was successful!
|
||||
*
|
||||
* This should return the Response sent back to the user, like a
|
||||
* RedirectResponse to the last page they visited.
|
||||
*
|
||||
* If you return null, the current request will continue, and the user
|
||||
* will be authenticated. This makes sense, for example, with an API.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TokenInterface $token
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
public function onAuthenticationSuccess(
|
||||
Request $request,
|
||||
TokenInterface $token,
|
||||
$providerKey
|
||||
) {
|
||||
// TODO: Implement onAuthenticationSuccess() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this method support remember me cookies?
|
||||
*
|
||||
* Remember me cookie will be set if *all* of the following are met:
|
||||
* A) This method returns true
|
||||
* B) The remember_me key under your firewall is configured
|
||||
* C) The "remember me" functionality is activated. This is usually
|
||||
* done by having a _remember_me checkbox in your form, but
|
||||
* can be configured by the "always_remember_me" and
|
||||
* "remember_me_parameter" parameters under the "remember_me" firewall
|
||||
* key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsRememberMe()
|
||||
{
|
||||
// TODO: Implement supportsRememberMe() method.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* doughnutwedding.com
|
||||
* Copyright (C) 2017 http://doughnutwedding.com eric@doughnutwedding.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Sikofitt\Security;
|
||||
|
||||
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
|
||||
|
||||
class ScryptEncoder implements PasswordEncoderInterface
|
||||
{
|
||||
/**
|
||||
* Encodes the raw password.
|
||||
*
|
||||
* @param string $raw The password to encode
|
||||
* @param string $salt The salt
|
||||
*
|
||||
* @return string The encoded password
|
||||
*/
|
||||
public function encodePassword($raw, $salt)
|
||||
{
|
||||
$salt = $this->generateSalt();
|
||||
$hash = \scrypt($raw, $salt, 16384, 8, 1, 32);
|
||||
|
||||
return 16384 .'$'. 8 .'$'. 1 .'$'.$salt.'$'.$hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a raw password against an encoded password.
|
||||
*
|
||||
* @param string $encoded An encoded password
|
||||
* @param string $raw A raw password
|
||||
* @param string $salt The salt
|
||||
*
|
||||
* @return bool true if the password is valid, false otherwise
|
||||
*/
|
||||
public function isPasswordValid($encoded, $raw, $salt)
|
||||
{
|
||||
$salt = null;
|
||||
// Is there actually a hash?
|
||||
if (!$encoded) {
|
||||
return false;
|
||||
}
|
||||
list($N, $r, $p, $salt, $hash) = explode('$', $encoded);
|
||||
// No empty fields?
|
||||
if (empty($N) or empty($r) or empty($p) or empty($salt) or empty($hash)) {
|
||||
return false;
|
||||
}
|
||||
// Are numeric values numeric?
|
||||
if (!is_numeric($N) or !is_numeric($r) or !is_numeric($p)) {
|
||||
return false;
|
||||
}
|
||||
$calculated = \scrypt($raw, $salt, $N, $r, $p, 32);
|
||||
// Use compareStrings to avoid timeing attacks
|
||||
return $this->compareStrings($hash, $calculated);
|
||||
}
|
||||
|
||||
private function compareStrings($expected, $actual)
|
||||
{
|
||||
$expected = (string) $expected;
|
||||
$actual = (string) $actual;
|
||||
$lenExpected = \mb_strlen($expected);
|
||||
$lenActual = \mb_strlen($actual);
|
||||
$len = min($lenExpected, $lenActual);
|
||||
$result = 0;
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$result |= ord($expected[$i]) ^ ord($actual[$i]);
|
||||
}
|
||||
$result |= $lenExpected ^ $lenActual;
|
||||
|
||||
return $result === 0;
|
||||
}
|
||||
|
||||
private function generateSalt()
|
||||
{
|
||||
$buffer = random_bytes(8);
|
||||
$salt = str_replace(['+', '$'], ['.', ''], base64_encode($buffer));
|
||||
|
||||
return $salt;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue