Skip to content

Commit

Permalink
data binding in forms
Browse files Browse the repository at this point in the history
  • Loading branch information
rikh42 committed Apr 11, 2012
1 parent 4716753 commit cc47a7e
Show file tree
Hide file tree
Showing 12 changed files with 372 additions and 47 deletions.
2 changes: 2 additions & 0 deletions src/example/controllers/DemoController.php
Expand Up @@ -60,6 +60,8 @@ public function formAction()
// Process form submissions
if ($form->onPostValid($this->getRequest()))
{
$mydata = $form->getData();

// redirect to hello
return $this->redirectResponse('hello', array('name'=>'Band'));
}
Expand Down
25 changes: 4 additions & 21 deletions src/example/resources/forms/DemoController/example.form.yml
Expand Up @@ -2,31 +2,14 @@
contactform:
type: form
label: Contact Information
method: post
children:
username:
type: text
label: Enter your name
validators:
Digits: ~
NotBlank: { message: Its Bad. }
binding: mapped
message:
type: textarea
label: Enter your message
option:
type: checkbox
label: Contact me when there is an update.
password:
type: password
label: Your password
pref:
type: choice
label: Choose your options
value: b
multiselect: false
expanded: false
choices:
a: First Option
b: second
c: third
d: forth
test:
type: hidden
value: 42
26 changes: 25 additions & 1 deletion src/example/resources/views/DemoController/form.twig
@@ -1,11 +1,28 @@
{% extends "example::layout.twig" %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link href="/css/bootstrap.css" rel="stylesheet">
<link href="/css/bootstrap-responsive.css" rel="stylesheet">
<link href="/css/doc.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">

<section class="main-content">
<div class="container">
<div class="row">
<div class="span12">

{% block header %}
<div class="page-header">
<h1>Form Test</h1>
</div>
{% endblock %}


{% block content %}
<div class="well">
<form class="form-horizontal" method="{{form.properties.method}}" action="{{path('form')}}">
Expand All @@ -19,3 +36,10 @@
<a href="{{path('home')}}">Home</a>
</p>
{% endblock %}
</div>
</div>
</div>
</section>
<script src="/js/prettify.js"></script>
</body>
</html>
36 changes: 32 additions & 4 deletions src/snb/core/ConfigSettings.php
Expand Up @@ -10,6 +10,9 @@
namespace snb\core;

use snb\core\ConfigInterface;
use snb\core\KernelInterface;
use snb\exceptions\CircularReferenceException;

use Symfony\Component\Yaml\Yaml;


Expand All @@ -19,6 +22,7 @@
class ConfigSettings implements ConfigInterface
{
protected $all;
protected $loading;


/**
Expand All @@ -27,6 +31,7 @@ class ConfigSettings implements ConfigInterface
public function __construct()
{
$this->all = array();
$this->loading = array();
}


Expand Down Expand Up @@ -93,13 +98,23 @@ public function remove($name)

/**
* Loads in a yaml config file, flattens it and stores the results
* in the config
* @param $file
* @param string $file - the name of the file to load
* @param KernelInterface $kernel
* @throws \snb\exceptions\CircularReferenceException
*/
public function load($file)
public function load($file, KernelInterface $kernel)
{
if (isset($this->loading[$file]))
throw new CircularReferenceException();

// we are now loading this file, so protect against loading it twice
$this->loading[$file] = true;

// try and find the file
$configPath = $kernel->findResource($file, 'config');

// Read in the content (file or string)
$content = Yaml::parse($file);
$content = Yaml::parse($configPath);

// bad data turns into an empty result
if ($content == null)
Expand All @@ -112,10 +127,23 @@ public function load($file)
// Flatten the content down
$flat = array();
$this->flatten($content, $flat);

// See if the file includes an import command
if (array_key_exists('import', $flat))
{
// Yes, so load that first
$this->load($flat['import'], $kernel);
}

// replace any items already set in the config, with the items from this file
$this->all = array_replace($this->all, $flat);

// no longer loading this file
unset($this->loading[$file]);
}



/**
* flatten
* Given a nested array, convert it to a flat array with
Expand Down
12 changes: 7 additions & 5 deletions src/snb/core/Kernel.php
Expand Up @@ -53,7 +53,7 @@ public function __construct($env, $starttime)
$this->logger = new Logger(new BufferedHandler());
$this->logger->logTime('Creating Kernel');
$this->container = new ServiceContainer();
$this->environment = $env;
$this->environment = preg_replace('/[^a-z0-9]/', '', mb_strtolower($env));
$this->packages = array();
}

Expand Down Expand Up @@ -132,17 +132,19 @@ protected function initServices()
{
// load the config and add it as a service
$config = new ConfigSettings();
$configPath = $this->findResource($this->getConfigName(), 'config');
$config->load($configPath);
//$configPath = $this->findResource($this->getConfigName(), 'config');
$config->load($this->getConfigName(), $this);

// Add some services that are part of the system
$this->addService('config', $config);
$this->addService('kernel', $this);
$this->addService('routes', 'snb\routing\RouteCollection');
$this->addService('event-dispatcher', new EventDispatcher);
$this->addService('logger', $this->logger);
$this->addService('template.engine', 'snb\view\TwigView');
$this->addService('database', 'snb\core\Database')->addCall('init', array());
$this->addService('form.builder', 'snb\form\FormBuilder')->setArguments(array('::service::kernel', '::service::logger'));
$this->addService('session', 'snb\http\SessionStorage')->addCall('start');
$this->addService('form.builder', 'snb\form\FormBuilder');
$this->addService('twig.extension.routing', 'snb\view\RouteExtension')->setArguments(array('::service::routes'));
$this->addService('twig.extension.forms', 'snb\view\FormExtension')->setArguments(array('::service::config'));

Expand All @@ -160,7 +162,7 @@ protected function initServices()
*/
protected function getConfigName()
{
return '::config.yml';
return '::config-'.$this->environment.'.yml';
}


Expand Down
26 changes: 14 additions & 12 deletions src/snb/form/FormBuilder.php
Expand Up @@ -13,6 +13,7 @@

namespace snb\form;
use snb\core\ContainerAware;
use snb\core\ContainerAwareInterface;
use snb\core\ContainerInterface;
use snb\core\KernelInterface;
use snb\logger\LoggerInterface;
Expand All @@ -22,23 +23,15 @@
/**
* A class to build forms from their yaml description
*/
class FormBuilder extends ContainerAware
class FormBuilder extends ContainerAware implements FormBuilderInterface
{
protected $kernel;
protected $logger;
protected $extensions;
protected $form;


/**
* @param \snb\core\KernelInterface $kernel
* @param null|\snb\logger\LoggerInterface $logger
*/
public function __construct(KernelInterface $kernel, LoggerInterface $logger=null)
public function __construct()
{
// remember these - we'll need them later.
$this->kernel = $kernel;
$this->logger = $logger;
$this->extensions = array();

// Add the core extensions
Expand All @@ -49,6 +42,7 @@ public function __construct(KernelInterface $kernel, LoggerInterface $logger=nul
'radio' => 'snb\form\type\RadioType',
'choice' => 'snb\form\type\ChoiceType',
'password' => 'snb\form\type\PasswordType',
'hidden' => 'snb\form\type\HiddenType',
'form' => 'snb\form\type\FormType',
'fieldset' => 'snb\form\type\FormType' // Alias of form
));
Expand All @@ -75,7 +69,7 @@ public function addExtensions(array $extensions)
public function loadForm($resource)
{
// Convert the resource name into a filename
$filename = $this->kernel->findResource($resource, 'forms');
$filename = $this->container->get('kernel')->findResource($resource, 'forms');

// Read in the content (file or string)
$content = Yaml::parse($filename);
Expand Down Expand Up @@ -113,13 +107,20 @@ public function loadFormElement(array $element, $defaultName)
// If the type is unknown, switch to text type
if (!array_key_exists($type, $this->extensions))
{
$this->logger->warning('Found unknown field type in form definition. Treating as Text', $type);
$this->container->get('logger')->warning('Found unknown field type in form definition. Treating as Text', $type);
$type = 'text';
}

// create the form element
$class = $this->extensions[$type];
$form = new $class;
if ($form instanceof ContainerAwareInterface)
{
$form->setContainer($this->container);
}

// Give the field a chance to act before any settings are loaded
$form->beforeLoad();

// default the name to the name of the element.
// may be overridden with the name: property
Expand Down Expand Up @@ -156,6 +157,7 @@ public function loadFormElement(array $element, $defaultName)
}
}

$form->afterLoad();
return $form;
}

Expand Down
20 changes: 20 additions & 0 deletions src/snb/form/FormBuilderInterface.php
@@ -0,0 +1,20 @@
<?php
/**
* This file is part of the Small Neat Box Framework
* Copyright (c) 2011-2012 Small Neat Box Ltd.
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/
/* This file based on part of the Symfony package.
* (c) Fabien Potencier <fabien@symfony.com>
*
*/


namespace snb\form;

interface FormBuilderInterface
{
public function addExtensions(array $extensions);
public function loadForm($resource);
}
2 changes: 1 addition & 1 deletion src/snb/form/FormView.php
Expand Up @@ -140,7 +140,7 @@ public function getProperties()
*/
public function offsetGet($name)
{
return $this->getChild($name);
return $this->children[$name];
}

/**
Expand Down

0 comments on commit cc47a7e

Please sign in to comment.