Added resume.js, updated gruntfile
This commit is contained in:
parent
3fb36fdfb1
commit
15627da05c
5
.php_cs
5
.php_cs
|
@ -22,11 +22,11 @@ $finder = Symfony\CS\Finder\DefaultFinder::create()
|
||||||
->in(__DIR__)
|
->in(__DIR__)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
return Symfony\CS\Config\Config::create()
|
return Symfony\CS\Config\Config::create()
|
||||||
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
|
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
|
||||||
->fixers(
|
->fixers(
|
||||||
[
|
[
|
||||||
|
'symfony',
|
||||||
'header_comment',
|
'header_comment',
|
||||||
'ordered_use',
|
'ordered_use',
|
||||||
'php_unit_construct',
|
'php_unit_construct',
|
||||||
|
@ -38,8 +38,7 @@ return Symfony\CS\Config\Config::create()
|
||||||
'phpdoc_order',
|
'phpdoc_order',
|
||||||
'short_array_syntax',
|
'short_array_syntax',
|
||||||
'short_echo_tag',
|
'short_echo_tag',
|
||||||
|
'-multiple_use'
|
||||||
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
->finder($finder)
|
->finder($finder)
|
||||||
|
|
37
Gruntfile.js
37
Gruntfile.js
|
@ -1,12 +1,14 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
bower: {
|
bower: {
|
||||||
js: {
|
js: {
|
||||||
dest: 'web/js/vendor',
|
dest: 'web/js/vendor',
|
||||||
options: {
|
options: {
|
||||||
checkExistence: false,
|
cleanTargetDir: true,
|
||||||
debugging: true,
|
checkExistence: true,
|
||||||
|
debugging: false,
|
||||||
paths: {
|
paths: {
|
||||||
bowerDirectory: 'vendor/bower',
|
bowerDirectory: 'vendor/bower',
|
||||||
bowerrc: '.bowerrc',
|
bowerrc: '.bowerrc',
|
||||||
|
@ -46,19 +48,42 @@ module.exports = function (grunt) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
configFiles: {
|
||||||
|
files: ['Gruntfile.js'],
|
||||||
|
options: {
|
||||||
|
reload: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dev: {
|
||||||
|
files: ['src/Sikofitt/less/*', 'src/Sikofitt/js/*'],
|
||||||
|
tasks: ['dev']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uglify: {
|
||||||
|
options: {
|
||||||
|
mangle: true,
|
||||||
|
compress: {
|
||||||
|
drop_console: true
|
||||||
|
},
|
||||||
|
banner: '/*! Resume.PHP - v<%= pkg.version %> - ' +
|
||||||
|
'<%= grunt.template.today("dddd, mmmm dS, yyyy, h:MM:ss tt") %> */',
|
||||||
|
nameCache: '.tmp/grunt-uglify-cache.json'
|
||||||
|
},
|
||||||
|
dist: {
|
||||||
|
files: {'web/js/resume.min.js': ['src/Sikofitt/js/resume.js']}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-less');
|
grunt.loadNpmTasks('grunt-contrib-less');
|
||||||
grunt.loadNpmTasks('main-bower-files');
|
grunt.loadNpmTasks('main-bower-files');
|
||||||
grunt.loadNpmTasks('grunt-phpunit');
|
grunt.loadNpmTasks('grunt-phpunit');
|
||||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
grunt.registerTask('dist', ['bower', 'less']);
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
|
grunt.registerTask('dist', ['bower', 'less', 'uglify', 'copy']);
|
||||||
|
grunt.registerTask('dev', ['less', 'uglify'])
|
||||||
grunt.registerTask('default', 'dist');
|
grunt.registerTask('default', 'dist');
|
||||||
|
|
||||||
};
|
};
|
|
@ -14,7 +14,7 @@ use Sikofitt\Json\JsonFileTrait;
|
||||||
use Sikofitt\Json\JsonTrait;
|
use Sikofitt\Json\JsonTrait;
|
||||||
use Silex\Application;
|
use Silex\Application;
|
||||||
|
|
||||||
require '../vendor/autoload.php';
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class App
|
* Class App
|
||||||
|
@ -31,6 +31,7 @@ class App extends Application
|
||||||
use Application\TranslationTrait;
|
use Application\TranslationTrait;
|
||||||
use Application\UrlGeneratorTrait;
|
use Application\UrlGeneratorTrait;
|
||||||
|
|
||||||
|
private $debug;
|
||||||
/**
|
/**
|
||||||
* Returns the application directory.
|
* Returns the application directory.
|
||||||
*
|
*
|
||||||
|
@ -108,6 +109,11 @@ class App extends Application
|
||||||
$this['env'] = null !== $this->config('app.environment') ? $this->config('app.environment') : 'dev';
|
$this['env'] = null !== $this->config('app.environment') ? $this->config('app.environment') : 'dev';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDebug()
|
||||||
|
{
|
||||||
|
return $this['debug'];
|
||||||
|
}
|
||||||
public function registerExtenders()
|
public function registerExtenders()
|
||||||
{
|
{
|
||||||
if (!$this['debug']) {
|
if (!$this['debug']) {
|
||||||
|
|
|
@ -5,6 +5,9 @@ app:
|
||||||
email: eric@rewiv.com
|
email: eric@rewiv.com
|
||||||
phone: 510-646-2135
|
phone: 510-646-2135
|
||||||
schema: https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json
|
schema: https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json
|
||||||
|
captcha: true
|
||||||
|
captcha_sitekey: 6LcvmSQTAAAAAMmf9w6mhCbpdLvknuD9SGVHT0q-
|
||||||
|
captcha_secret: 6LcvmSQTAAAAAITkvYJjgLar1LqGGLz-ic0ZMiXo
|
||||||
twig:
|
twig:
|
||||||
paths:
|
paths:
|
||||||
- views
|
- views
|
||||||
|
|
|
@ -9,51 +9,72 @@
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Silex\Provider\CsrfServiceProvider;
|
use Knp\Provider\ConsoleServiceProvider;
|
||||||
use Silex\Provider\LocaleServiceProvider;
|
use Sikofitt\Config\ConfigServiceProvider;
|
||||||
use Silex\Provider\TranslationServiceProvider;
|
use Sikofitt\Json\JsonServiceProvider;
|
||||||
use Silex\Provider\ValidatorServiceProvider;
|
use Silex\Provider\{
|
||||||
|
AssetServiceProvider,
|
||||||
|
CsrfServiceProvider,
|
||||||
|
FormServiceProvider,
|
||||||
|
HttpFragmentServiceProvider,
|
||||||
|
HttpKernelServiceProvider,
|
||||||
|
LocaleServiceProvider,
|
||||||
|
MonologServiceProvider,
|
||||||
|
RoutingServiceProvider,
|
||||||
|
ServiceControllerServiceProvider,
|
||||||
|
SessionServiceProvider,
|
||||||
|
TranslationServiceProvider,
|
||||||
|
TwigServiceProvider,
|
||||||
|
ValidatorServiceProvider,
|
||||||
|
VarDumperServiceProvider,
|
||||||
|
WebProfilerServiceProvider
|
||||||
|
};
|
||||||
|
use Symfony\Bridge\Monolog\Logger;
|
||||||
|
use WhoopsPimple\WhoopsServiceProvider;
|
||||||
|
|
||||||
$app->register(new \Sikofitt\Config\ConfigServiceProvider(), [
|
$app->register(new ConfigServiceProvider(), [
|
||||||
'config.path' => $app->getConfDirectory(),
|
'config.path' => $app->getConfDirectory(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$app->setDebug();
|
$app->setDebug();
|
||||||
|
|
||||||
|
$app
|
||||||
|
->register(new TwigServiceProvider(), [
|
||||||
|
'twig.path' => [
|
||||||
|
$app->getRootDirectory() . '/app/views',
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->register(new JsonServiceProvider())
|
||||||
|
->register(new AssetServiceProvider())
|
||||||
|
->register(new MonologServiceProvider())
|
||||||
|
->register(new SessionServiceProvider())
|
||||||
|
->register(new HttpKernelServiceProvider())
|
||||||
|
->register(new FormServiceProvider())
|
||||||
|
->register(new LocaleServiceProvider())
|
||||||
|
->register(new TranslationServiceProvider())
|
||||||
|
->register(new ValidatorServiceProvider())
|
||||||
|
->register(new CsrfServiceProvider())
|
||||||
|
->register(new MonologServiceProvider(), [
|
||||||
|
'monolog.logfile' => sprintf('%s/%s.log', $app->getLogDirectory(), $app['env']),
|
||||||
|
'monolog.name' => 'Resume.PHP',
|
||||||
|
'monolog.level' => $app->getDebug() ? Logger::DEBUG : Logger::INFO,
|
||||||
|
])
|
||||||
|
->register(new RoutingServiceProvider())
|
||||||
|
->register(new ServiceControllerServiceProvider())
|
||||||
|
->register(new HttpFragmentServiceProvider());
|
||||||
|
|
||||||
|
if ($app['debug'] || 0 === strcasecmp($app['env'], 'dev')) {
|
||||||
|
$app->register(new WebProfilerServiceProvider(), [
|
||||||
|
'profiler.cache_dir' => $app->getDataDirectory() . '/cache/profiler',
|
||||||
|
])
|
||||||
|
->register(new WhoopsServiceProvider())
|
||||||
|
->register(new VarDumperServiceProvider())
|
||||||
|
->register(new ConsoleServiceProvider(), [
|
||||||
|
'console.name' => 'Resume.PHP',
|
||||||
|
'console.version' => '0.0.1',
|
||||||
|
'console.project_directory' => $app->getAppDirectory(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
if (null === $app->config('app.schema')) {
|
if (null === $app->config('app.schema')) {
|
||||||
$app->config('app.schema', 'https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json');
|
$app->config('app.schema', 'https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
$app->register(new \Silex\Provider\TwigServiceProvider(), [
|
|
||||||
'twig.path' => [
|
|
||||||
$app->getRootDirectory() . '/app/views',
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
$app->register(new \Sikofitt\Json\JsonServiceProvider());
|
|
||||||
|
|
||||||
|
|
||||||
$app->register(new \Silex\Provider\AssetServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\MonologServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\SessionServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\HttpKernelServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\FormServiceProvider());
|
|
||||||
$app->register(new LocaleServiceProvider());
|
|
||||||
$app->register(new TranslationServiceProvider());
|
|
||||||
$app->register(new ValidatorServiceProvider());
|
|
||||||
$app->register(new CsrfServiceProvider());
|
|
||||||
|
|
||||||
$app->register(new \Silex\Provider\MonologServiceProvider(),
|
|
||||||
[
|
|
||||||
'monolog.logfile' => sprintf('%s/%s.log', $app->getLogDirectory(), $app['env']),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
$app->register(new \Silex\Provider\RoutingServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\ServiceControllerServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\HttpFragmentServiceProvider());
|
|
||||||
if ($app['debug'] || 0 === strcasecmp($app['env'], 'dev')) {
|
|
||||||
$app->register(new \Silex\Provider\WebProfilerServiceProvider(), [
|
|
||||||
'profiler.cache_dir' => $app->getDataDirectory() . '/cache/profiler',
|
|
||||||
]);
|
|
||||||
$app->register(new \WhoopsSilex\WhoopsServiceProvider());
|
|
||||||
$app->register(new \Silex\Provider\VarDumperServiceProvider());
|
|
||||||
}
|
|
||||||
|
|
|
@ -263,40 +263,5 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block javascripts_foot %}
|
{% block javascripts_foot %}
|
||||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block inline_js_foot %}
|
|
||||||
<script type="text/javascript">
|
|
||||||
jQuery(document).ready(function ($) {
|
|
||||||
jQuery('form#recaptcha').on('submit', function (event) {
|
|
||||||
event.stopImmediatePropagation();
|
|
||||||
event.stopPropagation();
|
|
||||||
jQuery.post(jQuery(this).attr('action'), jQuery(this).serialize(), function (response) {
|
|
||||||
|
|
||||||
data = JSON.parse(response);
|
|
||||||
if (false === data.valid) {
|
|
||||||
data.message.every(function (d) {
|
|
||||||
UIkit.notify('<i class="uk-icon-medium uk-icon-frown-o uk-icon-justify"></i> ' + d, {
|
|
||||||
pos: 'bottom-center',
|
|
||||||
status: 'danger'
|
|
||||||
});
|
|
||||||
})
|
|
||||||
} else if (true === data.valid) {
|
|
||||||
var divRoot = jQuery('<div />');
|
|
||||||
var h1 = jQuery('<h1 />');
|
|
||||||
var href = jQuery('<a />');
|
|
||||||
href
|
|
||||||
.attr('href', 'tel:' + data.message.phone)
|
|
||||||
.text(data.message.phone);
|
|
||||||
|
|
||||||
h1.append(href);
|
|
||||||
phone = jQuery('.hidden-phone');
|
|
||||||
phone.attr('href', 'tel:' + data.message.phone);
|
|
||||||
phone.text(data.message.phone);
|
|
||||||
divRoot.append(h1);
|
|
||||||
jQuery('#recaptcha-wrapper').replaceWith(divRoot);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en-gb" dir="ltr">
|
<html lang="en-us">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
@ -7,18 +7,18 @@
|
||||||
{% block meta %}{% endblock %}
|
{% block meta %}{% endblock %}
|
||||||
<title>{% block title %}Resume{% endblock %}</title>
|
<title>{% block title %}Resume{% endblock %}</title>
|
||||||
{% block shortcut_icon %}
|
{% block shortcut_icon %}
|
||||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
|
{# <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> #}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block apple_meta %}
|
{% block apple_meta %}
|
||||||
<link rel="apple-touch-icon-precomposed" href="images/apple-touch-icon.png">
|
{# <link rel="apple-touch-icon-precomposed" href="images/apple-touch-icon.png"> #}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<link rel="stylesheet" href="css/resume.min.css">
|
<link rel="stylesheet" href="{{ asset('css/resume.min.css') }}">
|
||||||
{% block stylesheets %}{% endblock %}
|
{% block stylesheets %}{% endblock %}
|
||||||
{% block inline_styles %}{% endblock %}
|
{% block inline_styles %}{% endblock %}
|
||||||
<script src="js/vendor/jquery.min.js"></script>
|
<script src="{{ asset('js/vendor/jquery.min.js') }}"></script>
|
||||||
<script src="js/vendor/uikit.min.js"></script>
|
<script src="{{ asset('js/vendor/uikit.min.js') }}"></script>
|
||||||
<script src="js/vendor/sticky.min.js"></script>
|
<script src="{{ asset('js/vendor/sticky.min.js') }}"></script>
|
||||||
<script src="{{ asset('js/vendor/notify.min.js') }}"></script>
|
<script src="{{ asset('js/vendor/notify.min.js') }}"></script>
|
||||||
{% block javascripts_head %}{% endblock %}
|
{% block javascripts_head %}{% endblock %}
|
||||||
{% block inline_js_head %}{% endblock %}
|
{% block inline_js_head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
<script src="{{ asset('js/resume.min.js') }}"></script>
|
||||||
{% block javascripts_foot %}{% endblock %}
|
{% block javascripts_foot %}{% endblock %}
|
||||||
{% block inline_js_foot %}{% endblock %}
|
{% block inline_js_foot %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
|
36
bin/console
36
bin/console
|
@ -2,15 +2,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Sikofitt\Command\SchemaValidationCommand;
|
use Sikofitt\Command\SchemaValidationCommand;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\{
|
||||||
use Symfony\Component\Console\Command\Command;
|
Console\Input\ArgvInput,
|
||||||
use Symfony\Component\Console\Command\HelpCommand;
|
Console\Input\InputOption,
|
||||||
use Symfony\Component\Console\Input\ArgvInput;
|
Debug\Debug
|
||||||
use Symfony\Component\Debug\Debug;
|
};
|
||||||
|
|
||||||
|
|
||||||
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
|
|
||||||
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
|
|
||||||
//umask(0000);
|
|
||||||
|
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
|
@ -21,14 +19,22 @@ set_time_limit(0);
|
||||||
require_once __DIR__. '/../vendor/autoload.php';
|
require_once __DIR__. '/../vendor/autoload.php';
|
||||||
|
|
||||||
$input = new ArgvInput();
|
$input = new ArgvInput();
|
||||||
$env = $input->getParameterOption(['--env', '-e'], getenv('SYMFONY_ENV') ?: 'dev');
|
|
||||||
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(['--no-debug', '']) && $env !== 'prod';
|
|
||||||
|
|
||||||
if ($debug) {
|
$app = new App();
|
||||||
Debug::enable();
|
require_once $app->getAppDirectory() . '/providers.php';
|
||||||
|
if($app->getDebug()) {
|
||||||
|
Debug::enable();
|
||||||
}
|
}
|
||||||
|
$application = $app['console'];
|
||||||
//$kernel = new AppKernel($env, $debug);
|
$application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', 'dev'));
|
||||||
$application = new Application();
|
$application->setDispatcher($app['dispatcher']);
|
||||||
|
$twigDebugCommand = new Symfony\Bridge\Twig\Command\DebugCommand('twig:debug');
|
||||||
|
$twigDebugCommand->setTwigEnvironment($app['twig']);
|
||||||
|
$twigLintCommand = new \Symfony\Bridge\Twig\Command\LintCommand('twig:lint');
|
||||||
|
$twigLintCommand->setTwigEnvironment($app['twig']);
|
||||||
$application->add(new SchemaValidationCommand());
|
$application->add(new SchemaValidationCommand());
|
||||||
|
$application->add($twigDebugCommand);
|
||||||
|
$application->add($twigLintCommand);
|
||||||
|
$application->add(new \Symfony\CS\Console\Command\FixCommand());
|
||||||
$application->run($input);
|
$application->run($input);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@
|
||||||
"silex/web-profiler": "^2.0",
|
"silex/web-profiler": "^2.0",
|
||||||
"twig/extensions": "^1.3",
|
"twig/extensions": "^1.3",
|
||||||
"symfony/config": "^3.1",
|
"symfony/config": "^3.1",
|
||||||
"symfony/security-csrf": "^3.1"
|
"symfony/security-csrf": "^3.1",
|
||||||
|
"knplabs/console-service-provider": "^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/debug": "~2.8|^3.0",
|
"symfony/debug": "~2.8|^3.0",
|
||||||
|
@ -53,7 +54,8 @@
|
||||||
"texthtml/whoops-silex": "^1.0",
|
"texthtml/whoops-silex": "^1.0",
|
||||||
"symfony/debug-bundle": "^3.1",
|
"symfony/debug-bundle": "^3.1",
|
||||||
"friendsofphp/php-cs-fixer": "^1.11",
|
"friendsofphp/php-cs-fixer": "^1.11",
|
||||||
"heroku/heroku-buildpack-php": "^108.0"
|
"heroku/heroku-buildpack-php": "^108.0",
|
||||||
|
"phpunit/phpunit": "^5.4"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "resume.php",
|
"name": "resume.php",
|
||||||
|
"version": "0.0.1",
|
||||||
"author": "R. Eric Wheeler <sikofitt@gmail.com>",
|
"author": "R. Eric Wheeler <sikofitt@gmail.com>",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://code.reric.me",
|
"homepage": "https://code.reric.me",
|
||||||
|
|
|
@ -14,22 +14,84 @@ namespace Sikofitt\Config;
|
||||||
use Noodlehaus\Config;
|
use Noodlehaus\Config;
|
||||||
use Pimple\Container;
|
use Pimple\Container;
|
||||||
use Pimple\ServiceProviderInterface;
|
use Pimple\ServiceProviderInterface;
|
||||||
|
use Silex\Api\BootableProviderInterface;
|
||||||
use Silex\Application;
|
use Silex\Application;
|
||||||
|
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\NotNull;
|
||||||
|
use Symfony\Component\Validator\Constraints\Regex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ConfigServiceProvider
|
* Class ConfigServiceProvider
|
||||||
|
*
|
||||||
* @package Sikofitt\Config
|
* @package Sikofitt\Config
|
||||||
*/
|
*/
|
||||||
class ConfigServiceProvider implements ServiceProviderInterface
|
class ConfigServiceProvider implements ServiceProviderInterface, BootableProviderInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Container $app
|
* @param Container $app
|
||||||
*/
|
*/
|
||||||
public function register(Container $app)
|
public function register(Container $app)
|
||||||
|
{
|
||||||
|
$app['config'] = function ($app) {
|
||||||
|
$config = Config::load($app['config.path']);
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function boot(Application $app)
|
||||||
{
|
{
|
||||||
$app['config'] = function ($app) {
|
$configItems = [
|
||||||
$config = Config::load($app['config.path']);
|
'email' => $app->config('app.email'),
|
||||||
return $config;
|
'phone' => $app->config('app.phone'),
|
||||||
};
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$constraints = [
|
||||||
|
'email' => [
|
||||||
|
new NotNull(['message' => 'Email value in app config is not present.']),
|
||||||
|
new NotBlank(['message' => 'Email should cannot be blank in config.']),
|
||||||
|
new Email(['message' => sprintf('Invalid email address in config. (%s)', $configItems['email'])]),
|
||||||
|
],
|
||||||
|
'phone' => [
|
||||||
|
new NotNull(['message' => 'Phone number value in app config is not present.']),
|
||||||
|
new NotBlank(['message' => 'Phone number cannot be blank in config.']),
|
||||||
|
new Length([
|
||||||
|
'min' => 10,
|
||||||
|
'minMessage' => sprintf('Invalid phone number, it should have at least 10 characters. %s given.', count($configItems['phone'])),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$captcha = $app->config('app.captcha');
|
||||||
|
if (isset($captcha) && $captcha) {
|
||||||
|
$configItems['captcha_sitekey'] = $app->config('app.captcha_sitekey');
|
||||||
|
$configItems['captcha_secret'] = $app->config('app.captcha_secret');
|
||||||
|
|
||||||
|
$constraints['captcha_sitekey'] = [
|
||||||
|
new NotNull(['message' => 'ReCaptcha sitekey is a required value to use the captcha, this check can be disabled by removing or setting the captcha config item to false.']),
|
||||||
|
new NotBlank(),
|
||||||
|
new Length(['min' => 40]),
|
||||||
|
];
|
||||||
|
$constraints['captcha_secret'] = [
|
||||||
|
new NotNull(),
|
||||||
|
new NotBlank(),
|
||||||
|
new Length(['min' => 40]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$errors = $app['validator']->validate($configItems, new Collection($constraints));
|
||||||
|
$validationErrors = [];
|
||||||
|
foreach ($errors->getIterator() as $error) {
|
||||||
|
$validationErrors[] = $error->getMessage();
|
||||||
|
}
|
||||||
|
if (count($validationErrors) > 0) {
|
||||||
|
throw new MissingConfigurationItemException($validationErrors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sikofitt\Config;
|
||||||
|
|
||||||
|
class MissingConfigurationItemException extends \InvalidArgumentException
|
||||||
|
{
|
||||||
|
}
|
|
@ -27,10 +27,10 @@ namespace Sikofitt\Controller;
|
||||||
use ReCaptcha\ReCaptcha;
|
use ReCaptcha\ReCaptcha;
|
||||||
use Silex\Api\ControllerProviderInterface;
|
use Silex\Api\ControllerProviderInterface;
|
||||||
use Silex\Application;
|
use Silex\Application;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class ApiControllerProvider implements ControllerProviderInterface
|
class ApiControllerProvider implements ControllerProviderInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -46,13 +46,13 @@ class ApiControllerProvider implements ControllerProviderInterface
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$controllers->get('/v1/schema', function () use($app) {
|
$controllers->get('/v1/schema', function () use ($app) {
|
||||||
|
|
||||||
$response = new Response(file_get_contents($app->getDataDirectory() . '/schema/schema.v1.json'), Response::HTTP_OK);
|
$response = new Response(file_get_contents($app->getDataDirectory() . '/schema/schema.v1.json'), Response::HTTP_OK);
|
||||||
$response->headers->set('Content-Type', 'application/schema+json');
|
$response->headers->set('Content-Type', 'application/schema+json');
|
||||||
return $response;
|
return $response;
|
||||||
});
|
});
|
||||||
$controllers->match('/v1/message', function(Request $request) use ($app) {
|
$controllers->match('/v1/message', function (Request $request) use ($app) {
|
||||||
/*$app->mail(\Swift_Message::newInstance()
|
/*$app->mail(\Swift_Message::newInstance()
|
||||||
->setSubject('[YourSite] Feedback')
|
->setSubject('[YourSite] Feedback')
|
||||||
->setFrom(array('noreply@yoursite.com'))
|
->setFrom(array('noreply@yoursite.com'))
|
||||||
|
|
|
@ -1,21 +1,29 @@
|
||||||
<?php
|
<?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.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Sikofitt\Form\Type;
|
namespace Sikofitt\Form\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\{
|
use Symfony\Component\Form\AbstractType;
|
||||||
FormBuilderInterface, AbstractType, Extension\Core\Type\SubmitType, Extension\Core\Type\EmailType, Extension\Core\Type\TextareaType, Extension\Core\Type\TextType, FormConfigInterface, FormInterface
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
};
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||||
use Symfony\Component\Security\Csrf\CsrfToken;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Validator\Constraints\{
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
Email,
|
use Symfony\Component\Form\FormConfigInterface;
|
||||||
Length,
|
use Symfony\Component\Form\FormInterface;
|
||||||
NotBlank
|
|
||||||
};
|
|
||||||
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Security\Csrf\CsrfToken;
|
||||||
|
use Symfony\Component\Validator\Constraints\Email;
|
||||||
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ContactType
|
* Class ContactType
|
||||||
|
@ -29,7 +37,7 @@ class ContactType extends AbstractType
|
||||||
* @param FormBuilderInterface $builder
|
* @param FormBuilderInterface $builder
|
||||||
* @param array $options
|
* @param array $options
|
||||||
*/
|
*/
|
||||||
public function buildForm (FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
->add('name', TextType::class, [
|
->add('name', TextType::class, [
|
||||||
|
@ -96,7 +104,7 @@ class ContactType extends AbstractType
|
||||||
*
|
*
|
||||||
* @param OptionsResolver $resolver
|
* @param OptionsResolver $resolver
|
||||||
*/
|
*/
|
||||||
public function configureOptions (OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
{
|
{
|
||||||
$resolver->setDefaults([
|
$resolver->setDefaults([
|
||||||
'attr' => [
|
'attr' => [
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
jQuery(document).ready(function ($) {
|
||||||
|
$('form#recaptcha').on('submit', function (event) {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
event.stopPropagation();
|
||||||
|
jQuery.post(jQuery(this).attr('action'), jQuery(this).serialize(), function (response) {
|
||||||
|
|
||||||
|
data = JSON.parse(response);
|
||||||
|
if (false === data.valid) {
|
||||||
|
data.message.every(function (d) {
|
||||||
|
UIkit.notify('<i class="uk-icon-medium uk-icon-frown-o uk-icon-justify"></i> ' + d, {
|
||||||
|
pos: 'bottom-center',
|
||||||
|
status: 'danger'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
} else if (true === data.valid) {
|
||||||
|
var divRoot = jQuery('<div />'),
|
||||||
|
h1 = jQuery('<h1 />'),
|
||||||
|
href = jQuery('<a />'),
|
||||||
|
phone = jQuery('.hidden-phone');
|
||||||
|
href
|
||||||
|
.attr('href', 'tel:' + data.message.phone)
|
||||||
|
.text(data.message.phone);
|
||||||
|
|
||||||
|
h1.append(href);
|
||||||
|
|
||||||
|
phone.attr('href', 'tel:' + data.message.phone);
|
||||||
|
phone.text(data.message.phone);
|
||||||
|
divRoot.append(h1);
|
||||||
|
jQuery('#recaptcha-wrapper').replaceWith(divRoot);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -49,3 +49,8 @@ a.profile-link {
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #ccc;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
.uk-close {
|
||||||
|
&:after {
|
||||||
|
font-size:30px;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue