Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhoryo committed Oct 24, 2011
0 parents commit 3239dd8
Show file tree
Hide file tree
Showing 46 changed files with 1,488 additions and 0 deletions.
18 changes: 18 additions & 0 deletions APYJsFormValidationBundle.php
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the JsFormValidationBundle.
*
* (c) Abhoryo <abhoryo@free.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace APY\JsFormValidationBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class APYJsFormValidationBundle extends Bundle
{
}
199 changes: 199 additions & 0 deletions CacheWarmer/JsFormValidationCacheWarmer.php
@@ -0,0 +1,199 @@
<?php

/*
* This file is part of the JsFormValidationBundle.
*
* (c) Abhoryo <abhoryo@free.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace APY\JsFormValidationBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Validator\Constraints;

use Assetic\AssetWriter;
use Assetic\AssetManager;
use Assetic\Factory\AssetFactory;
use Assetic\Factory\LazyAssetManager;
use Assetic\Filter\Yui\JsCompressorFilter;
use Assetic\FilterManager;
use Assetic\Asset\AssetCollection;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormError;

class JsFormValidationCacheWarmer implements CacheWarmerInterface
{
private $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

public function warmUp($cacheDir)
{
$enabled = $this->container->getParameter('apy_js_form_validation.enabled');
if ($enabled == true) {
$assets_warmer = $this->container->getParameter('apy_js_form_validation.assets_warmer');

foreach ($assets_warmer as $asset_warmer) {

if ($asset_warmer['form_fields'] == array('ALL')) {
$metadata = new ClassMetadata($asset_warmer['entity_class']);
$reflClass = $metadata->getReflectionClass();
$className = $reflClass->getName();

$form_fields = array();
foreach ($reflClass->getProperties() as $property) {
if ($property->getDeclaringClass()->getName() == $className) {
$form_fields[] = $property->getName();
}
}
$asset_warmer['form_fields'] = $form_fields;
}

$this->generateFormValidationScript($asset_warmer['entity_class'], $asset_warmer['form_name'], $asset_warmer['form_fields'], $asset_warmer['validation_groups'], true);
}
}
}

public function generateFormValidationScript($entityName, $formName = 'form', $formFields = array(), $formValidationGroups = array('Default'), $overwrite = false)
{
$asseticPath = $this->container->getParameter('assetic.write_to');
$scriptPath = $this->container->getParameter('apy_js_form_validation.script_directory');
$scriptFile = strtolower(str_replace(chr(92),'',$entityName)."_".$formName.'_'.implode("+",$formValidationGroups).".js");
$scriptRealPath = $asseticPath.$scriptPath;

if ( ! is_dir($scriptRealPath) ) {
mkdir($scriptRealPath, 0777, true);
}

if ( $overwrite || (false === file_exists($scriptRealPath.$scriptFile)) ) {

$metadata = new ClassMetadata($entityName);

// annotations constraints
$annotationloader = new AnnotationLoader(new AnnotationReader());
$annotationloader->loadClassMetadata($metadata);

// php constraints
// $entity = new $entityName();
// $entity->loadValidatorMetadata($metadata);

// yml constraints

// xml constraints

$librairyCalls = array();
$javascriptCalls = array();
$constraints = array();

foreach ($metadata->properties as $propertyName => $property) {
// Property presents in the form ?
if (in_array($propertyName, $formFields)) {
/* @var $property \PropertyMetadata */
foreach ($property->getConstraints() as $contraint) {
/* @var $contraint \ElementMetadata */

$contraintName = end((explode(chr(92), get_class($contraint))));
$contraintParameters = get_object_vars($contraint);

// Check validation groups
foreach ($contraintParameters['groups'] as $validationGroup) {
if (in_array($validationGroup, $formValidationGroups)) {
// Groups are no longer needed
unset($contraintParameters['groups']);

$librairies = "APYJsFormValidationBundle:Constraints:{$contraintName}Validator.js.twig";

if (!isset($librairyCalls[$contraintName])) {
$librairyCalls[$contraintName] = $librairies;
}

$javascriptConstraintParameters = array();
foreach ($contraintParameters as $variable => $value) {
if (is_array($value)) {
$value = json_encode($value);
}
else {
// regex
if (stristr('pattern', $variable) === FALSE) {
$value = "'".$value."'";
}
}

$javascriptConstraintParameters[] = "$variable:$value";
}

$javascriptConstraintParameters = '{'.join(', ',$javascriptConstraintParameters).'}';

$constraints[$formName."_".$propertyName][] = array(
'name' => $contraintName,
'parameters' => $javascriptConstraintParameters
);

break;
}
}
}
}
}

// Retrieve validation mode from configuration
$check_modes = array('submit' => false, 'blur' => false);
switch($this->container->getParameter('apy_js_form_validation.check_mode')) {
default:
case 'submit':
$check_modes['submit'] = true;
break;
case 'blur':
$check_modes['blur'] = true;
break;
case 'both':
$check_modes = array('submit' => true, 'blur' => true);
break;
}

// Render the validation script
$validation_bundle = $this->container->getParameter('apy_js_form_validation.validation_bundle');
$template = $this->container->get('templating')->render($validation_bundle.'::JsFormValidation.js.twig',
array(
'formName'=>$formName,
'fieldConstraints'=>$constraints,
'librairyCalls'=>$librairyCalls,
'check_modes'=>$check_modes
)
);

// Create asset and compress it
$asset = new AssetCollection();
$asset->setContent($template);
$asset->setTargetPath($scriptRealPath.$scriptFile);

// Js compression
if ($this->container->getParameter('apy_js_form_validation.yui_js')) {
$yui = new JsCompressorFilter($this->container->getParameter('assetic.filter.yui_js.jar'), $this->container->getParameter('assetic.java.bin'));
$yui->filterDump($asset);
}

if (false === @file_put_contents($asset->getTargetPath(), $asset->getContent())) {
throw new \RuntimeException('Unable to write file '.$asset->getTargetPath());
}
}

return $scriptPath.$scriptFile;
}

public function isOptional()
{
return true;
}
}
85 changes: 85 additions & 0 deletions DependencyInjection/APYJsFormValidationExtension.php
@@ -0,0 +1,85 @@
<?php

/*
* This file is part of the JsFormValidationBundle.
*
* (c) Abhoryo <abhoryo@free.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace APY\JsFormValidationBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\FileLocator;

class APYJsFormValidationExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$config = $processor->process($this->getConfigTree(), $configs);

$container->setParameter('apy_js_form_validation.enabled', $config['enabled']);
$container->setParameter('apy_js_form_validation.yui_js', $config['yui_js']);
$container->setParameter('apy_js_form_validation.check_mode', $config['check_mode']);
$container->setParameter('apy_js_form_validation.script_directory', $config['script_directory']);
$container->setParameter('apy_js_form_validation.validation_bundle', $config['validation_bundle']);
$container->setParameter('apy_js_form_validation.assets_warmer', $config['assets_warmer']);

$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}

private function getConfigTree()
{
$tb = new TreeBuilder();
return $tb
->root('apy_js_form_validation')
->children()
->booleanNode('enabled')->defaultValue(true)->end()
->booleanNode('yui_js')->defaultValue(false)->end()
->scalarNode('check_mode')
->defaultValue('both')
->validate()
->ifNotInArray(array('submit', 'blur', 'both'))
->thenInvalid('The %s mode is not supported')
->end()
->end()
->scalarNode('validation_bundle')->defaultValue('APYJsFormValidationBundle')->end()
->scalarNode('script_directory')->defaultValue('/bundles/jsformvalidation/js/')->end()
->arrayNode('assets_warmer')
->canBeUnset()
->prototype('array')
->children()
->scalarNode('entity_class')->isRequired()->end()
->scalarNode('form_name')->defaultValue('form')->end()
->arrayNode('form_fields')
->defaultValue(array('ALL'))
->beforeNormalization()
->ifTrue(function($v){ return !is_array($v); })
->then(function($v){ return array($v); })
->end()
->prototype('scalar')->end()
->end()
->arrayNode('validation_groups')
->defaultValue(array('Default'))
->beforeNormalization()
->ifTrue(function($v){ return !is_array($v); })
->then(function($v){ return array($v); })
->end()
->prototype('scalar')->end()
->end()
->end()
->end()
->end()
->end()
->end()
->buildTree();
}
}
32 changes: 32 additions & 0 deletions Form/Extension/FieldTypeExtension.php
@@ -0,0 +1,32 @@
<?php

/*
* This file is part of the JsFormValidationBundle.
*
* (c) Abhoryo <abhoryo@free.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace APY\JsFormValidationBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;

class FieldTypeExtension extends AbstractTypeExtension
{
public function getExtendedType()
{
return 'field';
}

public function buildView(FormView $view, FormInterface $form)
{
// Add validation groups to the view
if ($form->hasAttribute('validation_groups')) {
$view->set('validation_groups' , $form->getAttribute('validation_groups'));
}
}
}

0 comments on commit 3239dd8

Please sign in to comment.