Made document editing possible
This commit is contained in:
parent
1b55b079f4
commit
b82b4ffd34
@ -6,13 +6,17 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
|
||||
|
||||
use KekRozsak\FrontBundle\Entity\Document;
|
||||
use KekRozsak\FrontBundle\Form\Type\DocumentType;
|
||||
use KekRozsak\FrontBundle\Extensions\Slugifier;
|
||||
|
||||
class DocumentController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/dokumentum/{documentSlug}", name="KekRozsakFrontBundle_documentView")
|
||||
* @Template()
|
||||
*/
|
||||
public function documentViewAction($documentSlug)
|
||||
public function viewAction($documentSlug)
|
||||
{
|
||||
$docRepo = $this->getDoctrine()->getRepository('KekRozsakFrontBundle:Document');
|
||||
if (!($document = $docRepo->findOneBySlug($documentSlug)))
|
||||
@ -22,4 +26,86 @@ class DocumentController extends Controller
|
||||
'document' => $document,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/dokumentumok/uj/{groupSlug}", name="KekRozsakFrontBundle_documentCreate", defaults={"groupslug"=""})
|
||||
* @Template()
|
||||
*/
|
||||
public function createAction($groupSlug = '')
|
||||
{
|
||||
$groupRepo = $this->getDoctrine()->getRepository('KekRozsakFrontBundle:Group');
|
||||
$group = $groupRepo->findOneBySlug($groupSlug);
|
||||
/* TODO: make group fully optional */
|
||||
|
||||
$document = new Document();
|
||||
$document->setSlug('n-a');
|
||||
$form = $this->createForm(new DocumentType(), $document);
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->getMethod() == 'POST')
|
||||
{
|
||||
$form->bindRequest($request);
|
||||
|
||||
if ($form->isValid())
|
||||
{
|
||||
$slugifier = new Slugifier();
|
||||
$document->setSlug($slugifier->slugify($document->getTitle()));
|
||||
$document->setCreatedAt(new \DateTime('now'));
|
||||
$document->setCreatedBy($this->get('security.context')->getToken()->getUser());
|
||||
|
||||
if ($group)
|
||||
{
|
||||
$group->addDocument($document);
|
||||
$document->addGroup($group);
|
||||
}
|
||||
|
||||
$em = $this->getDoctrine()->getEntityManager();
|
||||
$em->persist($document);
|
||||
$em->flush();
|
||||
|
||||
/* TODO: return to group list if groupSlug is empty! */
|
||||
return $this->redirect($this->generateUrl('KekRozsakFrontBundle_groupDocuments', array('groupSlug' => $group->getSlug())));
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'defaultGroup' => $groupSlug,
|
||||
'form' => $form->createView(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/dokumentum/{documentSlug}/szerkesztes", name="KekRozsakFrontBundle_documentEdit")
|
||||
* @Template()
|
||||
*/
|
||||
public function editAction($documentSlug)
|
||||
{
|
||||
$documentRepo = $this->getDoctrine()->getRepository('KekRozsakFrontBundle:Document');
|
||||
if (!($document = $documentRepo->findOneBySlug($documentSlug)))
|
||||
throw $this->createNotFoundException('A kért dokumentum nem létezik!');
|
||||
$form = $this->createForm(new DocumentType(), $document);
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->getMethod() == 'POST')
|
||||
{
|
||||
$form->bindRequest($request);
|
||||
if ($form->isValid())
|
||||
{
|
||||
$slugifier = new Slugifier();
|
||||
$document->setSlug($slugifier->slugify($document->getTitle()));
|
||||
// TODO: add updatedAt, updatedBy, updateReason, etc.
|
||||
|
||||
$em = $this->getDoctrine()->getEntityManager();
|
||||
$em->persist($document);
|
||||
$em->flush();
|
||||
|
||||
return $this->redirect($this->generateUrl('KekRozsakFrontBundle_documentView', array('documentSlug' => $document->getSlug())));
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'document' => $document,
|
||||
'form' => $form->createView(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ namespace KekRozsak\FrontBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
|
||||
|
||||
use KekRozsak\SecurityBundle\Entity\User;
|
||||
use KekRozsak\FrontBundle\Entity\Group;
|
||||
@ -12,6 +14,8 @@ use KekRozsak\FrontBundle\Entity\Group;
|
||||
* KekRozsak\FrontBundle\Entity\Document
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="documents")
|
||||
* @DoctrineAssert\UniqueEntity(fields={"title"}, message="Ilyen című dokumentum már létezik. Kérlek válassz másikat!")
|
||||
* @DoctrineAssert\UniqueEntity(fields={"slug"}, message="Ilyen című dokumentum már létezik. Kérlek válassz másikat!")
|
||||
*/
|
||||
class Document
|
||||
{
|
||||
@ -41,6 +45,7 @@ class Document
|
||||
/**
|
||||
* @var string $title
|
||||
* @ORM\Column(type="string", length=150, unique=true, nullable=false)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
@ -69,6 +74,7 @@ class Document
|
||||
/**
|
||||
* @var string $slug
|
||||
* @ORM\Column(type="string", length=150, unique=true, nullable=false)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $slug;
|
||||
|
||||
@ -207,4 +213,88 @@ class Document
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var KekRozsak\SecurityBundle\Entity\User $updatedBy
|
||||
* @ORM\ManyToOne(targetEntity="KekRozsak\SecurityBundle\Entity\User")
|
||||
*/
|
||||
protected $updatedBy;
|
||||
|
||||
/**
|
||||
* Set updatedBy
|
||||
*
|
||||
* @param KekRozsak\SecurityBundle\Entity\User $updatedBy
|
||||
* @return Document
|
||||
*/
|
||||
public function setUpdatedBy(\KekRozsak\SecurityBundle\Entity\User $updatedBy = null)
|
||||
{
|
||||
$this->updatedBy = $updatedBy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updatedBy
|
||||
*
|
||||
* @return KekRozsak\SecurityBundle\Entity\User
|
||||
*/
|
||||
public function getUpdatedBy()
|
||||
{
|
||||
return $this->updatedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var DateTime $updatedAt
|
||||
* @ORM\Column(type="datetime", nullable=true)
|
||||
*/
|
||||
protected $updatedAt;
|
||||
|
||||
/**
|
||||
* Set updatedAt
|
||||
*
|
||||
* @param DateTime $updatedAt
|
||||
* @return Document
|
||||
*/
|
||||
public function setUpdatedAt(\DateTime $updatedAt = null)
|
||||
{
|
||||
$this->updatedAt = $updatedAt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updatedAt
|
||||
*
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getUpdatedAt()
|
||||
{
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string updateReason
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
protected $updateReason;
|
||||
|
||||
/**
|
||||
* Set updateReason
|
||||
*
|
||||
* @param string $updateReason
|
||||
* @return Document
|
||||
*/
|
||||
public function setUpdateReason($updateReason = null)
|
||||
{
|
||||
$this->updateReason = $updateReason;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updateReason
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdateReason()
|
||||
{
|
||||
return $this->updateReason;
|
||||
}
|
||||
}
|
||||
|
27
src/KekRozsak/FrontBundle/Form/Type/DocumentType.php
Normal file
27
src/KekRozsak/FrontBundle/Form/Type/DocumentType.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace KekRozsak\FrontBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class DocumentType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add('title', null, array(
|
||||
'label' => 'A dokumentum címe',
|
||||
));
|
||||
|
||||
$builder->add('content', 'ckeditor', array(
|
||||
'label' => ' ',
|
||||
));
|
||||
|
||||
/* TODO: possibility to add to other groups! */
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'document';
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{% extends '::main_template.html.twig' %}
|
||||
{% block title %} - Dokumentum létrehozása{% endblock %}
|
||||
{% block content %}
|
||||
<h3>Új dokumentum létrehozása</h3>
|
||||
<form method="post" action="{{ path('KekRozsakFrontBundle_documentCreate', { groupSlug: defaultGroup }) }}">
|
||||
{{ form_widget(form) }}
|
||||
<button type="submit">Mentés</button>
|
||||
</form>
|
||||
{% endblock content %}
|
@ -1,7 +0,0 @@
|
||||
{% extends '::main_template.html.twig' %}
|
||||
{% block title %} - Dokumentum - {{ document.title }}{% endblock %}
|
||||
{% block content %}
|
||||
<h3>{{ document.title }}</h3>
|
||||
{{ document.content }}
|
||||
<div class="szerzo">{{ document.createdBy.displayName }}</div>
|
||||
{% endblock content %}
|
@ -0,0 +1,9 @@
|
||||
{% extends '::main_template.html.twig' %}
|
||||
{% block title %} - Dokumentum szerkesztése - {{ document.title }}{% endblock %}
|
||||
{% block content %}
|
||||
<h3>Dokumentum szerkesztése - {{ document.title }}</h3>
|
||||
<form method="post" action="{{ path('KekRozsakFrontBundle_documentEdit', { documentSlug: document.slug }) }}">
|
||||
{{ form_widget(form) }}
|
||||
<button type="submit">Mentés</button>
|
||||
</form>
|
||||
{% endblock content %}
|
@ -0,0 +1,9 @@
|
||||
{% extends '::main_template.html.twig' %}
|
||||
{% block title %} - Dokumentum - {{ document.title }}{% endblock %}
|
||||
{% block content %}
|
||||
<h3>
|
||||
{{ document.title }}{% if document.createdBy == app.user %} [ <a href="{{ path('KekRozsakFrontBundle_documentEdit', { documentSlug: document.slug }) }}">Szerkesztés</a> ] {% endif %}
|
||||
</h3>
|
||||
{{ document.content|raw }}
|
||||
<div class="szerzo">{{ document.createdBy.displayName }}</div>
|
||||
{% endblock content %}
|
@ -9,9 +9,25 @@
|
||||
<li><a href="{{ path('KekRozsakFrontBundle_groupMembers', { groupSlug: group.slug }) }}">Tagok</a></li>
|
||||
</ul>
|
||||
<h3>{{ group.name }} - Dokumentumok</h3>
|
||||
<ul>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td colspan="2">Cím</td>
|
||||
<td>Készítette</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for document in group.documents %}
|
||||
<li><a href="{{ path('KekRozsakFrontBundle_documentView', { documentSlug: document.slug }) }}">{{ document.title }}</a></li>
|
||||
<tr>
|
||||
<td>[ikon]</td>
|
||||
<td><a href="{{ path('KekRozsakFrontBundle_documentView', { documentSlug: document.slug }) }}">{{ document.title }}</a></td>
|
||||
<td>
|
||||
{{ document.createdBy.displayName }}<br />
|
||||
{{ document.createdAt|date('Y-m-d H:i') }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{{ path('KekRozsakFrontBundle_documentCreate', { groupSlug: group.slug }) }}">Új dokumentum</a>
|
||||
{% endblock %}
|
||||
|
502
vendor/composer/installed.json
vendored
502
vendor/composer/installed.json
vendored
@ -3,7 +3,7 @@
|
||||
"name": "jms/metadata",
|
||||
"version": "1.1.1",
|
||||
"version_normalized": "1.1.1.0",
|
||||
"time": "2011-12-29 19:32:49",
|
||||
"time": "2011-12-29 14:32:49",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/metadata",
|
||||
@ -47,7 +47,7 @@
|
||||
"name": "jms/cg",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"time": "2011-12-29 18:40:52",
|
||||
"time": "2011-12-29 13:40:52",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/schmittjoh/cg-library.git",
|
||||
@ -89,7 +89,7 @@
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"target-dir": "JMS/AopBundle",
|
||||
"time": "2011-12-29 18:50:26",
|
||||
"time": "2011-12-29 13:50:26",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/JMSAopBundle",
|
||||
@ -133,7 +133,7 @@
|
||||
"version": "1.1.0",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"target-dir": "JMS/SecurityExtraBundle",
|
||||
"time": "2011-12-29 22:38:12",
|
||||
"time": "2011-12-29 17:38:12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/JMSSecurityExtraBundle",
|
||||
@ -178,7 +178,7 @@
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"target-dir": "JMS/DiExtraBundle",
|
||||
"time": "2012-02-24 14:01:54",
|
||||
"time": "2012-02-24 09:01:54",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/JMSDiExtraBundle",
|
||||
@ -221,7 +221,7 @@
|
||||
"name": "doctrine/common",
|
||||
"version": "2.2.2",
|
||||
"version_normalized": "2.2.2.0",
|
||||
"time": "2012-04-06 21:46:44",
|
||||
"time": "2012-04-06 11:46:44",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/common",
|
||||
@ -287,7 +287,7 @@
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.1.0",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"time": "2012-04-17 08:27:40",
|
||||
"time": "2012-04-16 22:27:40",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
@ -337,7 +337,7 @@
|
||||
"name": "twig/extensions",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-05-15 15:28:19",
|
||||
"time": "2012-05-15 05:28:19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Twig-extensions",
|
||||
@ -378,71 +378,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kriswallsmith/assetic",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-06-06 19:41:54",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/kriswallsmith/assetic.git",
|
||||
"reference": "d6f89a3170c5280ad554347dc113eb25fdf00ad7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/kriswallsmith/assetic/zipball/d6f89a3170c5280ad554347dc113eb25fdf00ad7",
|
||||
"reference": "d6f89a3170c5280ad554347dc113eb25fdf00ad7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"symfony/process": "2.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"twig/twig": ">=1.6.0,<2.0",
|
||||
"leafo/lessphp": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"twig/twig": "Assetic provides the integration with the Twig templating engine",
|
||||
"leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kris Wallsmith",
|
||||
"email": "kris.wallsmith@gmail.com",
|
||||
"homepage": "http://kriswallsmith.net/",
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Asset Management for PHP",
|
||||
"homepage": "https://github.com/kriswallsmith/assetic",
|
||||
"keywords": [
|
||||
"assets",
|
||||
"compression",
|
||||
"minification"
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Assetic": "src/"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "doctrine/doctrine-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Doctrine/Bundle/DoctrineBundle",
|
||||
"time": "2012-07-02 04:42:17",
|
||||
"time": "2012-07-01 18:42:17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/doctrine/DoctrineBundle.git",
|
||||
@ -516,7 +457,7 @@
|
||||
"name": "doctrine/orm",
|
||||
"version": "2.2.x-dev",
|
||||
"version_normalized": "2.2.9999999.9999999-dev",
|
||||
"time": "2012-07-06 01:48:00",
|
||||
"time": "2012-07-05 15:48:00",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/doctrine/doctrine2.git",
|
||||
@ -581,7 +522,7 @@
|
||||
"name": "doctrine/dbal",
|
||||
"version": "2.2.x-dev",
|
||||
"version_normalized": "2.2.9999999.9999999-dev",
|
||||
"time": "2012-07-07 12:30:35",
|
||||
"time": "2012-07-07 02:30:35",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal",
|
||||
@ -647,7 +588,7 @@
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Sensio/Bundle/GeneratorBundle",
|
||||
"time": "2012-07-12 18:04:48",
|
||||
"time": "2012-07-12 08:04:48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sensio/SensioGeneratorBundle",
|
||||
@ -695,68 +636,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/assetic-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Symfony/Bundle/AsseticBundle",
|
||||
"time": "2012-07-12 00:51:17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/AsseticBundle",
|
||||
"reference": "ed933dcfa45f00b6bc6d7727007403f3ff429e5a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/symfony/AsseticBundle/zipball/ed933dcfa45f00b6bc6d7727007403f3ff429e5a",
|
||||
"reference": "ed933dcfa45f00b6bc6d7727007403f3ff429e5a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"symfony/framework-bundle": "2.1.*",
|
||||
"kriswallsmith/assetic": "1.1.*"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/twig-bundle": "2.1.*"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kris Wallsmith",
|
||||
"email": "kris.wallsmith@gmail.com",
|
||||
"homepage": "http://kriswallsmith.net/",
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Integrates Assetic into Symfony2",
|
||||
"homepage": "https://github.com/symfony/AsseticBundle",
|
||||
"keywords": [
|
||||
"assets",
|
||||
"compression",
|
||||
"minification"
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Bundle\\AsseticBundle": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/monolog-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Symfony/Bundle/MonologBundle",
|
||||
"time": "2012-06-29 23:48:07",
|
||||
"time": "2012-06-29 13:48:07",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/MonologBundle",
|
||||
@ -816,7 +701,7 @@
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Sensio/Bundle/FrameworkExtraBundle",
|
||||
"time": "2012-07-11 17:13:52",
|
||||
"time": "2012-07-11 07:13:52",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sensio/SensioFrameworkExtraBundle",
|
||||
@ -861,124 +746,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-07-15 17:42:44",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/fabpot/Twig.git",
|
||||
"reference": "d45664045194ef62573c153c424508527105041e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/fabpot/Twig/zipball/d45664045194ef62573c153c424508527105041e",
|
||||
"reference": "d45664045194ef62573c153c424508527105041e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"BSD-3"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": null,
|
||||
"role": null
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"homepage": null,
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "http://twig.sensiolabs.org",
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig_": "lib/"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/swiftmailer-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Symfony/Bundle/SwiftmailerBundle",
|
||||
"time": "2012-07-05 05:33:34",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/SwiftmailerBundle",
|
||||
"reference": "v2.1.0-BETA3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/symfony/SwiftmailerBundle/zipball/v2.1.0-BETA3",
|
||||
"reference": "v2.1.0-BETA3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"symfony/swiftmailer-bridge": "2.1.*",
|
||||
"swiftmailer/swiftmailer": ">=4.2.0,<4.3-dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "2.1.*",
|
||||
"symfony/http-kernel": "2.1.*",
|
||||
"symfony/config": "2.1.*"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": null,
|
||||
"role": null
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"email": null,
|
||||
"homepage": "http://symfony.com/contributors",
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Symfony SwiftmailerBundle",
|
||||
"homepage": "http://symfony.com",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Bundle\\SwiftmailerBundle": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-07-13 06:47:17",
|
||||
"time": "2012-07-12 20:47:17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/swiftmailer/swiftmailer.git",
|
||||
@ -1034,7 +806,7 @@
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Sensio/Bundle/DistributionBundle",
|
||||
"time": "2012-07-15 04:24:10",
|
||||
"time": "2012-07-14 18:24:10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sensio/SensioDistributionBundle",
|
||||
@ -1073,12 +845,71 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/swiftmailer-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Symfony/Bundle/SwiftmailerBundle",
|
||||
"time": "2012-07-19 01:55:12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/SwiftmailerBundle",
|
||||
"reference": "65e6079443c3cd413012e146aa74307f18671f42"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/symfony/SwiftmailerBundle/zipball/65e6079443c3cd413012e146aa74307f18671f42",
|
||||
"reference": "65e6079443c3cd413012e146aa74307f18671f42",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"symfony/swiftmailer-bridge": "2.1.*",
|
||||
"swiftmailer/swiftmailer": ">=4.2.0,<4.3-dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "2.1.*",
|
||||
"symfony/http-kernel": "2.1.*",
|
||||
"symfony/config": "2.1.*"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": null,
|
||||
"role": null
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"email": null,
|
||||
"homepage": "http://symfony.com/contributors",
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Symfony SwiftmailerBundle",
|
||||
"homepage": "http://symfony.com",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Bundle\\SwiftmailerBundle": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "egeloen/ckeditor-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Ivory/CKEditorBundle",
|
||||
"time": "2012-05-28 13:16:47",
|
||||
"time": "2012-05-28 11:16:47",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/egeloen/IvoryCKEditorBundle",
|
||||
@ -1118,19 +949,188 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/symfony",
|
||||
"name": "kriswallsmith/assetic",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-07-17 09:07:53",
|
||||
"time": "2012-07-20 10:33:33",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/symfony/symfony.git",
|
||||
"reference": "f52ce6178243e4b11aa09bde147f684d596fb120"
|
||||
"url": "http://github.com/kriswallsmith/assetic.git",
|
||||
"reference": "5c1c9b658b732a980312e8f29cec4e175c2bb6b2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/symfony/symfony/zipball/f52ce6178243e4b11aa09bde147f684d596fb120",
|
||||
"reference": "f52ce6178243e4b11aa09bde147f684d596fb120",
|
||||
"url": "https://github.com/kriswallsmith/assetic/zipball/5c1c9b658b732a980312e8f29cec4e175c2bb6b2",
|
||||
"reference": "5c1c9b658b732a980312e8f29cec4e175c2bb6b2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"symfony/process": "2.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"twig/twig": ">=1.6.0,<2.0",
|
||||
"leafo/lessphp": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"twig/twig": "Assetic provides the integration with the Twig templating engine",
|
||||
"leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kris Wallsmith",
|
||||
"email": "kris.wallsmith@gmail.com",
|
||||
"homepage": "http://kriswallsmith.net/",
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Asset Management for PHP",
|
||||
"homepage": "https://github.com/kriswallsmith/assetic",
|
||||
"keywords": [
|
||||
"assets",
|
||||
"compression",
|
||||
"minification"
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Assetic": "src/"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/assetic-bundle",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"target-dir": "Symfony/Bundle/AsseticBundle",
|
||||
"time": "2012-07-20 19:34:07",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/AsseticBundle",
|
||||
"reference": "e5e9a56a872d9e1f305d14cd8296bf77888388af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/symfony/AsseticBundle/zipball/e5e9a56a872d9e1f305d14cd8296bf77888388af",
|
||||
"reference": "e5e9a56a872d9e1f305d14cd8296bf77888388af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"symfony/framework-bundle": "2.1.*",
|
||||
"kriswallsmith/assetic": "1.1.*"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/twig-bundle": "2.1.*"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kris Wallsmith",
|
||||
"email": "kris.wallsmith@gmail.com",
|
||||
"homepage": "http://kriswallsmith.net/",
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Integrates Assetic into Symfony2",
|
||||
"homepage": "https://github.com/symfony/AsseticBundle",
|
||||
"keywords": [
|
||||
"assets",
|
||||
"compression",
|
||||
"minification"
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Bundle\\AsseticBundle": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-07-20 12:41:38",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/fabpot/Twig.git",
|
||||
"reference": "8a84838798e45424c5fe2d87149db6855ae037bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/fabpot/Twig/zipball/8a84838798e45424c5fe2d87149db6855ae037bf",
|
||||
"reference": "8a84838798e45424c5fe2d87149db6855ae037bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "source",
|
||||
"license": [
|
||||
"BSD-3"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": null,
|
||||
"role": null
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"homepage": null,
|
||||
"role": null
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "http://twig.sensiolabs.org",
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig_": "lib/"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "symfony/symfony",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"time": "2012-07-21 11:16:18",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/symfony/symfony.git",
|
||||
"reference": "6c256b01b087f94a4ec04487d875fe81375eb6c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/symfony/symfony/zipball/6c256b01b087f94a4ec04487d875fe81375eb6c1",
|
||||
"reference": "6c256b01b087f94a4ec04487d875fe81375eb6c1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
4
vendor/kriswallsmith/assetic/.gitignore
vendored
Normal file
4
vendor/kriswallsmith/assetic/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
phpunit.xml
|
||||
vendor/
|
||||
composer.phar
|
||||
composer.lock
|
2
vendor/kriswallsmith/assetic/composer.json
vendored
2
vendor/kriswallsmith/assetic/composer.json
vendored
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "kriswallsmith/assetic",
|
||||
"minimum-stability": "dev",
|
||||
"description": "Asset Management for PHP",
|
||||
"keywords": ["assets", "compression", "minification"],
|
||||
"homepage": "https://github.com/kriswallsmith/assetic",
|
||||
@ -20,6 +21,7 @@
|
||||
"twig/twig": ">=1.6.0,<2.0",
|
||||
"leafo/lessphp": "*"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"suggest": {
|
||||
"twig/twig": "Assetic provides the integration with the Twig templating engine",
|
||||
"leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler"
|
||||
|
@ -25,6 +25,7 @@ use Symfony\Component\Process\ProcessBuilder;
|
||||
class CompassFilter implements FilterInterface
|
||||
{
|
||||
private $compassPath;
|
||||
private $rubyPath;
|
||||
private $scss;
|
||||
|
||||
// sass options
|
||||
@ -50,9 +51,10 @@ class CompassFilter implements FilterInterface
|
||||
private $generatedImagesPath;
|
||||
private $httpJavascriptsPath;
|
||||
|
||||
public function __construct($compassPath = '/usr/bin/compass')
|
||||
public function __construct($compassPath = '/usr/bin/compass', $rubyPath = null)
|
||||
{
|
||||
$this->compassPath = $compassPath;
|
||||
$this->rubyPath = $rubyPath;
|
||||
$this->cacheLocation = sys_get_temp_dir();
|
||||
|
||||
if ('cli' !== php_sapi_name()) {
|
||||
@ -133,6 +135,11 @@ class CompassFilter implements FilterInterface
|
||||
$this->plugins[] = $plugin;
|
||||
}
|
||||
|
||||
public function setLoadPaths(array $loadPaths)
|
||||
{
|
||||
$this->loadPaths = $loadPaths;
|
||||
}
|
||||
|
||||
public function addLoadPath($loadPath)
|
||||
{
|
||||
$this->loadPaths[] = $loadPath;
|
||||
@ -171,11 +178,16 @@ class CompassFilter implements FilterInterface
|
||||
// compass does not seems to handle symlink, so we use realpath()
|
||||
$tempDir = realpath(sys_get_temp_dir());
|
||||
|
||||
$pb = new ProcessBuilder(array(
|
||||
$compassProcessArgs = array(
|
||||
$this->compassPath,
|
||||
'compile',
|
||||
$tempDir,
|
||||
));
|
||||
);
|
||||
if (null !== $this->rubyPath) {
|
||||
array_unshift($compassProcessArgs, $this->rubyPath);
|
||||
}
|
||||
|
||||
$pb = new ProcessBuilder($compassProcessArgs);
|
||||
$pb->inheritEnvironmentVariables();
|
||||
|
||||
if ($this->force) {
|
||||
@ -330,12 +342,12 @@ class CompassFilter implements FilterInterface
|
||||
|
||||
// does we have an associative array ?
|
||||
if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) {
|
||||
foreach($array as $name => $value) {
|
||||
foreach ($array as $name => $value) {
|
||||
$output[] = sprintf(' :%s => "%s"', $name, addcslashes($value, '\\'));
|
||||
}
|
||||
$output = "{\n".implode(",\n", $output)."\n}";
|
||||
} else {
|
||||
foreach($array as $name => $value) {
|
||||
foreach ($array as $name => $value) {
|
||||
$output[] = sprintf(' "%s"', addcslashes($value, '\\'));
|
||||
}
|
||||
$output = "[\n".implode(",\n", $output)."\n]";
|
||||
|
@ -30,6 +30,7 @@ class SassFilter implements FilterInterface
|
||||
const STYLE_COMPRESSED = 'compressed';
|
||||
|
||||
private $sassPath;
|
||||
private $rubyPath;
|
||||
private $unixNewlines;
|
||||
private $scss;
|
||||
private $style;
|
||||
@ -41,9 +42,10 @@ class SassFilter implements FilterInterface
|
||||
private $noCache;
|
||||
private $compass;
|
||||
|
||||
public function __construct($sassPath = '/usr/bin/sass')
|
||||
public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
|
||||
{
|
||||
$this->sassPath = $sassPath;
|
||||
$this->rubyPath = $rubyPath;
|
||||
$this->cacheLocation = realpath(sys_get_temp_dir());
|
||||
}
|
||||
|
||||
@ -99,7 +101,12 @@ class SassFilter implements FilterInterface
|
||||
|
||||
public function filterLoad(AssetInterface $asset)
|
||||
{
|
||||
$pb = new ProcessBuilder(array($this->sassPath));
|
||||
$sassProcessArgs = array($this->sassPath);
|
||||
if (null !== $this->rubyPath) {
|
||||
array_unshift($sassProcessArgs, $this->rubyPath);
|
||||
}
|
||||
|
||||
$pb = new ProcessBuilder($sassProcessArgs);
|
||||
|
||||
$root = $asset->getSourceRoot();
|
||||
$path = $asset->getSourcePath();
|
||||
|
@ -19,9 +19,9 @@ namespace Assetic\Filter\Sass;
|
||||
*/
|
||||
class ScssFilter extends SassFilter
|
||||
{
|
||||
public function __construct($sassPath = '/usr/bin/sass')
|
||||
public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
|
||||
{
|
||||
parent::__construct($sassPath);
|
||||
parent::__construct($sassPath, $rubyPath);
|
||||
|
||||
$this->setScss(true);
|
||||
}
|
||||
|
@ -80,11 +80,10 @@ abstract class BaseCompressorFilter implements FilterInterface
|
||||
|
||||
// input and output files
|
||||
$tempDir = realpath(sys_get_temp_dir());
|
||||
$hash = substr(sha1(time().rand(11111, 99999)), 0, 7);
|
||||
$input = $tempDir.DIRECTORY_SEPARATOR.$hash.'.'.$type;
|
||||
$output = $tempDir.DIRECTORY_SEPARATOR.$hash.'-min.'.$type;
|
||||
$input = tempnam($tempDir, 'YUI-IN-');
|
||||
$output = tempnam($tempDir, 'YUI-OUT-');
|
||||
file_put_contents($input, $content);
|
||||
$pb->add('-o')->add($output)->add($input);
|
||||
$pb->add('-o')->add($output)->add('--type')->add($type)->add($input);
|
||||
|
||||
$proc = $pb->getProcess();
|
||||
$code = $proc->run();
|
||||
|
@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
if (!$loader = @include __DIR__.'/../vendor/.composer/autoload.php') {
|
||||
if (!$loader = @include __DIR__.'/../vendor/autoload.php') {
|
||||
die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
|
||||
'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
|
||||
'php composer.phar install'.PHP_EOL);
|
||||
@ -43,4 +43,4 @@ if (isset($_SERVER['PACKAGER'])) {
|
||||
|
||||
if (isset($_SERVER['PACKER'])) {
|
||||
require_once $_SERVER['PACKER'];
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class DumpCommand extends ContainerAwareCommand
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln(sprintf('Dumping all <comment>%s</comment> assets.', $input->getOption('env')));
|
||||
$output->writeln(sprintf('Debug mode is <comment>%s</comment>.', $input->getOption('no-debug') ? 'off' : 'on'));
|
||||
$output->writeln(sprintf('Debug mode is <comment>%s</comment>.', $this->am->isDebug() ? 'on' : 'off'));
|
||||
$output->writeln('');
|
||||
|
||||
if (!$input->getOption('watch')) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
<service id="assetic.filter.compass" class="%assetic.filter.compass.class%">
|
||||
<tag name="assetic.filter" alias="compass" />
|
||||
<argument>%assetic.filter.compass.bin%</argument>
|
||||
<argument>%assetic.ruby.bin%</argument>
|
||||
<call method="setDebugInfo"><argument>%assetic.filter.compass.debug%</argument></call>
|
||||
<call method="setStyle"><argument>%assetic.filter.compass.style%</argument></call>
|
||||
<call method="setImagesDir"><argument>%assetic.filter.compass.images_dir%</argument></call>
|
||||
|
@ -15,6 +15,7 @@
|
||||
<service id="assetic.filter.sass" class="%assetic.filter.sass.class%">
|
||||
<tag name="assetic.filter" alias="sass" />
|
||||
<argument>%assetic.filter.sass.bin%</argument>
|
||||
<argument>%assetic.ruby.bin%</argument>
|
||||
<call method="setStyle"><argument>%assetic.filter.sass.style%</argument></call>
|
||||
<call method="setCompass"><argument>%assetic.filter.sass.compass%</argument></call>
|
||||
</service>
|
||||
|
@ -15,6 +15,7 @@
|
||||
<service id="assetic.filter.scss" class="%assetic.filter.scss.class%">
|
||||
<tag name="assetic.filter" alias="scss" />
|
||||
<argument>%assetic.filter.scss.sass%</argument>
|
||||
<argument>%assetic.ruby.bin%</argument>
|
||||
<call method="setStyle"><argument>%assetic.filter.scss.style%</argument></call>
|
||||
<call method="setCompass"><argument>%assetic.filter.scss.compass%</argument></call>
|
||||
</service>
|
||||
|
@ -46,7 +46,13 @@
|
||||
{% endfor %}
|
||||
|
||||
<p>
|
||||
<pre>{{ message.body|e('html', message.charset)|convert_encoding('UTF-8', message.charset) }}</pre>
|
||||
<pre>
|
||||
{%- if message.charset %}
|
||||
{{- message.body|e('html', message.charset)|convert_encoding('UTF-8', message.charset) }}
|
||||
{%- else %}
|
||||
{{- message.body|e('html') }}
|
||||
{%- endif -%}
|
||||
</pre>
|
||||
</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
36
vendor/symfony/symfony/UPGRADE-2.1.md
vendored
36
vendor/symfony/symfony/UPGRADE-2.1.md
vendored
@ -13,14 +13,15 @@
|
||||
configuration (i.e. `config.yml`), merging could yield a set of base URL's
|
||||
for multiple environments.
|
||||
|
||||
* The priorities for the built-in listeners have changed:
|
||||
|
||||
2.0 2.1
|
||||
security.firewall request 64 8
|
||||
locale listener early_request 253 255
|
||||
request -1 16
|
||||
router listener early_request 255 128
|
||||
request 10 32
|
||||
* The priorities for the built-in listeners have changed.
|
||||
|
||||
```
|
||||
2.0 2.1
|
||||
security.firewall kernel.request 64 8
|
||||
locale listener kernel.request 0 16
|
||||
router listener early_request 255 n/a
|
||||
request 0 32
|
||||
```
|
||||
|
||||
### Doctrine
|
||||
|
||||
@ -106,7 +107,7 @@
|
||||
if ($locale = $request->attributes->get('_locale')) {
|
||||
$request->getSession()->set('_locale', $locale);
|
||||
} else {
|
||||
$request->setDefaultLocale($request->getSession()->get('_locale', $this->defaultLocale));
|
||||
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1053,10 +1054,25 @@
|
||||
$registry->addType($registry->resolveType(new MyFormType()));
|
||||
```
|
||||
|
||||
* The method `renderBlock()` of the helper for the PHP Templating component was
|
||||
deprecated and will be removed in Symfony 2.3. You should use `block()` instead.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
```
|
||||
|
||||
### Validator
|
||||
|
||||
* The methods `setMessage()`, `getMessageTemplate()` and
|
||||
`getMessageParameters()` in the Constraint class were deprecated and will
|
||||
`getMessageParameters()` in the `ConstraintValidator` class were deprecated and will
|
||||
be removed in Symfony 2.3.
|
||||
|
||||
If you have implemented custom validators, you should use the
|
||||
|
@ -9,3 +9,4 @@ CHANGELOG
|
||||
* DoctrineOrmTypeGuesser now guesses "collection" for array Doctrine type
|
||||
* DoctrineType now caches its choice lists in order to improve performance
|
||||
* DoctrineType now uses ManagerRegistry::getManagerForClass() if the option "em" is not set
|
||||
* UniqueEntity validation constraint now accepts a "repositoryMethod" option that will be used to check for uniqueness instead of the default "findBy"
|
||||
|
@ -12,11 +12,12 @@
|
||||
namespace Symfony\Bridge\Doctrine\Form;
|
||||
|
||||
use Doctrine\Common\Persistence\ManagerRegistry;
|
||||
use Doctrine\Common\Persistence\Mapping\MappingException;
|
||||
use Doctrine\ORM\Mapping\MappingException as LegacyMappingException;
|
||||
use Symfony\Component\Form\FormTypeGuesserInterface;
|
||||
use Symfony\Component\Form\Guess\Guess;
|
||||
use Symfony\Component\Form\Guess\TypeGuess;
|
||||
use Symfony\Component\Form\Guess\ValueGuess;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
|
||||
class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
{
|
||||
@ -145,6 +146,8 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
return $this->cache[$class] = array($em->getClassMetadata($class), $name);
|
||||
} catch (MappingException $e) {
|
||||
// not an entity or mapped super class
|
||||
} catch (LegacyMappingException $e) {
|
||||
// not an entity or mapped super class, using Doctrine ORM 2.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ abstract class DoctrineType extends AbstractType
|
||||
return $choiceListCache[$hash];
|
||||
};
|
||||
|
||||
$emFilter = function (Options $options, $em) use ($registry) {
|
||||
$emNormalizer = function (Options $options, $em) use ($registry) {
|
||||
/* @var ManagerRegistry $registry */
|
||||
if (null !== $em) {
|
||||
return $registry->getManager($em);
|
||||
@ -134,8 +134,8 @@ abstract class DoctrineType extends AbstractType
|
||||
'group_by' => null,
|
||||
));
|
||||
|
||||
$resolver->setFilters(array(
|
||||
'em' => $emFilter,
|
||||
$resolver->setNormalizers(array(
|
||||
'em' => $emNormalizer,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,50 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
return $registry;
|
||||
}
|
||||
|
||||
protected function createRepositoryMock()
|
||||
{
|
||||
$repository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository')
|
||||
->setMethods(array('findByCustom', 'find', 'findAll', 'findOneBy', 'findBy', 'getClassName'))
|
||||
->getMock()
|
||||
;
|
||||
|
||||
return $repository;
|
||||
}
|
||||
|
||||
protected function createEntityManagerMock($repositoryMock)
|
||||
{
|
||||
$em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')
|
||||
->getMock()
|
||||
;
|
||||
$em->expects($this->any())
|
||||
->method('getRepository')
|
||||
->will($this->returnValue($repositoryMock))
|
||||
;
|
||||
|
||||
$classMetadata = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata');
|
||||
$classMetadata
|
||||
->expects($this->any())
|
||||
->method('hasField')
|
||||
->will($this->returnValue(true))
|
||||
;
|
||||
$refl = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionProperty')
|
||||
->disableOriginalConstructor()
|
||||
->getMock()
|
||||
;
|
||||
$refl
|
||||
->expects($this->any())
|
||||
->method('getValue')
|
||||
->will($this->returnValue(true))
|
||||
;
|
||||
$classMetadata->reflFields = array('name' => $refl);
|
||||
$em->expects($this->any())
|
||||
->method('getClassMetadata')
|
||||
->will($this->returnValue($classMetadata))
|
||||
;
|
||||
|
||||
return $em;
|
||||
}
|
||||
|
||||
protected function createMetadataFactoryMock($metadata)
|
||||
{
|
||||
$metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
|
||||
@ -69,7 +113,7 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
return $validatorFactory;
|
||||
}
|
||||
|
||||
public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null, $errorPath = null)
|
||||
public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null, $errorPath = null, $repositoryMethod = 'findBy')
|
||||
{
|
||||
if (!$validateClass) {
|
||||
$validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity';
|
||||
@ -83,7 +127,13 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
$uniqueValidator = new UniqueEntityValidator($registry);
|
||||
|
||||
$metadata = new ClassMetadata($validateClass);
|
||||
$metadata->addConstraint(new UniqueEntity(array('fields' => $uniqueFields, 'em' => $entityManagerName, 'errorPath' => $errorPath)));
|
||||
$constraint = new UniqueEntity(array(
|
||||
'fields' => $uniqueFields,
|
||||
'em' => $entityManagerName,
|
||||
'errorPath' => $errorPath,
|
||||
'repositoryMethod' => $repositoryMethod
|
||||
));
|
||||
$metadata->addConstraint($constraint);
|
||||
|
||||
$metadataFactory = $this->createMetadataFactoryMock($metadata);
|
||||
$validatorFactory = $this->createValidatorFactory($uniqueValidator);
|
||||
@ -194,6 +244,23 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
$this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.');
|
||||
}
|
||||
|
||||
public function testValidateUniquenessUsingCustomRepositoryMethod()
|
||||
{
|
||||
$entityManagerName = 'foo';
|
||||
$repository = $this->createRepositoryMock();
|
||||
$repository->expects($this->once())
|
||||
->method('findByCustom')
|
||||
->will($this->returnValue(array()))
|
||||
;
|
||||
$em = $this->createEntityManagerMock($repository);
|
||||
$validator = $this->createValidator($entityManagerName, $em, null, array(), null, 'findByCustom');
|
||||
|
||||
$entity1 = new SingleIdentEntity(1, 'foo');
|
||||
|
||||
$violationsList = $validator->validate($entity1);
|
||||
$this->assertEquals(0, $violationsList->count(), 'Violation is using custom repository method.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group GH-1635
|
||||
*/
|
||||
|
@ -24,6 +24,7 @@ class UniqueEntity extends Constraint
|
||||
public $message = 'This value is already used.';
|
||||
public $service = 'doctrine.orm.validator.unique';
|
||||
public $em = null;
|
||||
public $repositoryMethod = 'findBy';
|
||||
public $fields = array();
|
||||
public $errorPath = null;
|
||||
|
||||
|
@ -100,7 +100,7 @@ class UniqueEntityValidator extends ConstraintValidator
|
||||
}
|
||||
|
||||
$repository = $em->getRepository($className);
|
||||
$result = $repository->findBy($criteria);
|
||||
$result = $repository->{$constraint->repositoryMethod}($criteria);
|
||||
|
||||
/* If the result is a MongoCursor, it must be advanced to the first
|
||||
* element. Rewinding should have no ill effect if $result is another
|
||||
|
@ -12,11 +12,9 @@
|
||||
namespace Symfony\Bridge\Twig\Extension;
|
||||
|
||||
use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
use Symfony\Bridge\Twig\Form\TwigRendererInterface;
|
||||
use Symfony\Component\Form\FormViewInterface;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
use Symfony\Component\Form\Util\FormUtil;
|
||||
|
||||
/**
|
||||
* FormExtension extends Twig with form capabilities.
|
||||
@ -26,21 +24,17 @@ use Symfony\Component\Form\Util\FormUtil;
|
||||
*/
|
||||
class FormExtension extends \Twig_Extension
|
||||
{
|
||||
protected $csrfProvider;
|
||||
protected $resources;
|
||||
protected $blocks;
|
||||
protected $environment;
|
||||
protected $themes;
|
||||
protected $varStack;
|
||||
protected $template;
|
||||
/**
|
||||
* This property is public so that it can be accessed directly from compiled
|
||||
* templates without having to call a getter, which slightly decreases performance.
|
||||
*
|
||||
* @var \Symfony\Component\Form\FormRendererInterface
|
||||
*/
|
||||
public $renderer;
|
||||
|
||||
public function __construct(CsrfProviderInterface $csrfProvider = null, array $resources = array())
|
||||
public function __construct(TwigRendererInterface $renderer)
|
||||
{
|
||||
$this->csrfProvider = $csrfProvider;
|
||||
$this->themes = new \SplObjectStorage();
|
||||
$this->varStack = array();
|
||||
$this->blocks = new \SplObjectStorage();
|
||||
$this->resources = $resources;
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,25 +42,11 @@ class FormExtension extends \Twig_Extension
|
||||
*/
|
||||
public function initRuntime(\Twig_Environment $environment)
|
||||
{
|
||||
$this->environment = $environment;
|
||||
$this->renderer->setEnvironment($environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a theme for a given view.
|
||||
*
|
||||
* @param FormView $view A FormView instance
|
||||
* @param array|string $resources An array of resource names|a resource name
|
||||
*/
|
||||
public function setTheme(FormView $view, $resources)
|
||||
{
|
||||
$this->themes->attach($view, (array) $resources);
|
||||
$this->blocks = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token parser instance to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_TokenParser instances
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTokenParsers()
|
||||
{
|
||||
@ -76,305 +56,39 @@ class FormExtension extends \Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return array(
|
||||
'form_enctype' => new \Twig_Function_Method($this, 'renderEnctype', array('is_safe' => array('html'))),
|
||||
'form_widget' => new \Twig_Function_Method($this, 'renderWidget', array('is_safe' => array('html'))),
|
||||
'form_errors' => new \Twig_Function_Method($this, 'renderErrors', array('is_safe' => array('html'))),
|
||||
'form_label' => new \Twig_Function_Method($this, 'renderLabel', array('is_safe' => array('html'))),
|
||||
'form_row' => new \Twig_Function_Method($this, 'renderRow', array('is_safe' => array('html'))),
|
||||
'form_rest' => new \Twig_Function_Method($this, 'renderRest', array('is_safe' => array('html'))),
|
||||
'csrf_token' => new \Twig_Function_Method($this, 'getCsrfToken'),
|
||||
'_form_is_choice_group' => new \Twig_Function_Method($this, 'isChoiceGroup', array('is_safe' => array('html'))),
|
||||
'_form_is_choice_selected' => new \Twig_Function_Method($this, 'isChoiceSelected', array('is_safe' => array('html'))),
|
||||
'form_enctype' => new \Twig_Function_Method($this, 'renderer->renderEnctype', array('is_safe' => array('html'))),
|
||||
'form_widget' => new \Twig_Function_Method($this, 'renderer->renderWidget', array('is_safe' => array('html'))),
|
||||
'form_errors' => new \Twig_Function_Method($this, 'renderer->renderErrors', array('is_safe' => array('html'))),
|
||||
'form_label' => new \Twig_Function_Method($this, 'renderer->renderLabel', array('is_safe' => array('html'))),
|
||||
'form_row' => new \Twig_Function_Method($this, 'renderer->renderRow', array('is_safe' => array('html'))),
|
||||
'form_rest' => new \Twig_Function_Method($this, 'renderer->renderRest', array('is_safe' => array('html'))),
|
||||
'csrf_token' => new \Twig_Function_Method($this, 'renderer->renderCsrfToken'),
|
||||
'_form_is_choice_group' => new \Twig_Function_Method($this, 'renderer->isChoiceGroup', array('is_safe' => array('html'))),
|
||||
'_form_is_choice_selected' => new \Twig_Function_Method($this, 'renderer->isChoiceSelected', array('is_safe' => array('html'))),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return array(
|
||||
'humanize' => new \Twig_Filter_Function(__NAMESPACE__.'\humanize'),
|
||||
'humanize' => new \Twig_Filter_Method($this, 'renderer->humanize'),
|
||||
);
|
||||
}
|
||||
|
||||
public function isChoiceGroup($label)
|
||||
{
|
||||
return FormUtil::isChoiceGroup($label);
|
||||
}
|
||||
|
||||
public function isChoiceSelected(FormView $view, ChoiceView $choice)
|
||||
{
|
||||
return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the HTML enctype in the form tag, if necessary
|
||||
*
|
||||
* Example usage in Twig templates:
|
||||
*
|
||||
* <form action="..." method="post" {{ form_enctype(form) }}>
|
||||
*
|
||||
* @param FormView $view The view for which to render the encoding type
|
||||
*
|
||||
* @return string The html markup
|
||||
*/
|
||||
public function renderEnctype(FormView $view)
|
||||
{
|
||||
return $this->render($view, 'enctype');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a row for the view.
|
||||
*
|
||||
* @param FormView $view The view to render as a row
|
||||
* @param array $variables An array of variables
|
||||
*
|
||||
* @return string The html markup
|
||||
*/
|
||||
public function renderRow(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->render($view, 'row', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders views which have not already been rendered.
|
||||
*
|
||||
* @param FormView $view The parent view
|
||||
* @param array $variables An array of variables
|
||||
*
|
||||
* @return string The html markup
|
||||
*/
|
||||
public function renderRest(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->render($view, 'rest', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the HTML for a given view
|
||||
*
|
||||
* Example usage in Twig:
|
||||
*
|
||||
* {{ form_widget(view) }}
|
||||
*
|
||||
* You can pass options during the call:
|
||||
*
|
||||
* {{ form_widget(view, {'attr': {'class': 'foo'}}) }}
|
||||
*
|
||||
* {{ form_widget(view, {'separator': '+++++'}) }}
|
||||
*
|
||||
* @param FormView $view The view to render
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
*/
|
||||
public function renderWidget(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->render($view, 'widget', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the errors of the given view
|
||||
*
|
||||
* @param FormView $view The view to render the errors for
|
||||
*
|
||||
* @return string The html markup
|
||||
*/
|
||||
public function renderErrors(FormView $view)
|
||||
{
|
||||
return $this->render($view, 'errors');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the label of the given view
|
||||
*
|
||||
* @param FormView $view The view to render the label for
|
||||
* @param string $label Label name
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
*/
|
||||
public function renderLabel(FormView $view, $label = null, array $variables = array())
|
||||
{
|
||||
if ($label !== null) {
|
||||
$variables += array('label' => $label);
|
||||
}
|
||||
|
||||
return $this->render($view, 'label', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a template.
|
||||
*
|
||||
* 1. This function first looks for a block named "_<view id>_<section>",
|
||||
* 2. if such a block is not found the function will look for a block named
|
||||
* "<type name>_<section>",
|
||||
* 3. the type name is recursively replaced by the parent type name until a
|
||||
* corresponding block is found
|
||||
*
|
||||
* @param FormView $view The form view
|
||||
* @param string $section The section to render (i.e. 'row', 'widget', 'label', ...)
|
||||
* @param array $variables Additional variables
|
||||
*
|
||||
* @return string The html markup
|
||||
*
|
||||
* @throws FormException if no template block exists to render the given section of the view
|
||||
*/
|
||||
protected function render(FormView $view, $section, array $variables = array())
|
||||
{
|
||||
$mainTemplate = in_array($section, array('widget', 'row'));
|
||||
|
||||
if ($mainTemplate && $view->isRendered()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (null === $this->template) {
|
||||
$this->template = reset($this->resources);
|
||||
if (!$this->template instanceof \Twig_Template) {
|
||||
$this->template = $this->environment->loadTemplate($this->template);
|
||||
}
|
||||
}
|
||||
|
||||
$custom = '_'.$view->getVar('id');
|
||||
$rendering = $custom.$section;
|
||||
$blocks = $this->getBlocks($view);
|
||||
|
||||
if (isset($this->varStack[$rendering])) {
|
||||
$typeIndex = $this->varStack[$rendering]['typeIndex'] - 1;
|
||||
$types = $this->varStack[$rendering]['types'];
|
||||
$this->varStack[$rendering]['variables'] = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
|
||||
} else {
|
||||
$types = $view->getVar('types');
|
||||
$types[] = $view->getVar('full_block_name');
|
||||
$typeIndex = count($types) - 1;
|
||||
$this->varStack[$rendering] = array(
|
||||
'variables' => array_replace_recursive($view->getVars(), $variables),
|
||||
'types' => $types,
|
||||
);
|
||||
}
|
||||
|
||||
do {
|
||||
$types[$typeIndex] .= '_'.$section;
|
||||
|
||||
if (isset($blocks[$types[$typeIndex]])) {
|
||||
$this->varStack[$rendering]['typeIndex'] = $typeIndex;
|
||||
|
||||
$context = $this->environment->mergeGlobals($this->varStack[$rendering]['variables']);
|
||||
|
||||
// we do not call renderBlock here to avoid too many nested level calls (XDebug limits the level to 100 by default)
|
||||
ob_start();
|
||||
$this->template->displayBlock($types[$typeIndex], $context, $blocks);
|
||||
$html = ob_get_clean();
|
||||
|
||||
if ($mainTemplate) {
|
||||
$view->setRendered();
|
||||
}
|
||||
|
||||
unset($this->varStack[$rendering]);
|
||||
|
||||
return $html;
|
||||
}
|
||||
} while (--$typeIndex >= 0);
|
||||
|
||||
throw new FormException(sprintf(
|
||||
'Unable to render the form as none of the following blocks exist: "%s".',
|
||||
implode('", "', array_reverse($types))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CSRF token.
|
||||
*
|
||||
* Use this helper for CSRF protection without the overhead of creating a
|
||||
* form.
|
||||
*
|
||||
* <code>
|
||||
* <input type="hidden" name="token" value="{{ csrf_token('rm_user_' ~ user.id) }}">
|
||||
* </code>
|
||||
*
|
||||
* Check the token in your action using the same intention.
|
||||
*
|
||||
* <code>
|
||||
* $csrfProvider = $this->get('form.csrf_provider');
|
||||
* if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) {
|
||||
* throw new \RuntimeException('CSRF attack detected.');
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $intention The intention of the protected action
|
||||
*
|
||||
* @return string A CSRF token
|
||||
*/
|
||||
public function getCsrfToken($intention)
|
||||
{
|
||||
if (!$this->csrfProvider instanceof CsrfProviderInterface) {
|
||||
throw new \BadMethodCallException('CSRF token can only be generated if a CsrfProviderInterface is injected in the constructor.');
|
||||
}
|
||||
|
||||
return $this->csrfProvider->generateCsrfToken($intention);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the blocks used to render the view.
|
||||
*
|
||||
* Templates are looked for in the resources in the following order:
|
||||
* * resources from the themes (and its parents)
|
||||
* * resources from the themes of parent views (up to the root view)
|
||||
* * default resources
|
||||
*
|
||||
* @param FormView $view The view
|
||||
*
|
||||
* @return array An array of Twig_TemplateInterface instances
|
||||
*/
|
||||
protected function getBlocks(FormView $view)
|
||||
{
|
||||
if (!$this->blocks->contains($view)) {
|
||||
$rootView = !$view->hasParent();
|
||||
|
||||
$templates = $rootView ? $this->resources : array();
|
||||
|
||||
if (isset($this->themes[$view])) {
|
||||
$templates = array_merge($templates, $this->themes[$view]);
|
||||
}
|
||||
|
||||
$blocks = array();
|
||||
|
||||
foreach ($templates as $template) {
|
||||
if (!$template instanceof \Twig_Template) {
|
||||
$template = $this->environment->loadTemplate($template);
|
||||
}
|
||||
|
||||
$templateBlocks = array();
|
||||
do {
|
||||
$templateBlocks = array_merge($template->getBlocks(), $templateBlocks);
|
||||
} while (false !== $template = $template->getParent(array()));
|
||||
$blocks = array_merge($blocks, $templateBlocks);
|
||||
}
|
||||
|
||||
if (!$rootView) {
|
||||
$blocks = array_merge($this->getBlocks($view->getParent()), $blocks);
|
||||
}
|
||||
|
||||
$this->blocks->attach($view, $blocks);
|
||||
} else {
|
||||
$blocks = $this->blocks[$view];
|
||||
}
|
||||
|
||||
return $blocks;
|
||||
}
|
||||
}
|
||||
|
||||
function humanize($text)
|
||||
{
|
||||
return ucfirst(trim(strtolower(preg_replace('/[_\s]+/', ' ', $text))));
|
||||
}
|
||||
|
41
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRenderer.php
vendored
Normal file
41
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRenderer.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Form;
|
||||
|
||||
use Symfony\Component\Form\FormRenderer;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class TwigRenderer extends FormRenderer implements TwigRendererInterface
|
||||
{
|
||||
/**
|
||||
* @var TwigRendererEngineInterface
|
||||
*/
|
||||
private $engine;
|
||||
|
||||
public function __construct(TwigRendererEngineInterface $engine, CsrfProviderInterface $csrfProvider = null)
|
||||
{
|
||||
parent::__construct($engine, $csrfProvider);
|
||||
|
||||
$this->engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setEnvironment(\Twig_Environment $environment)
|
||||
{
|
||||
$this->engine->setEnvironment($environment);
|
||||
}
|
||||
}
|
183
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRendererEngine.php
vendored
Normal file
183
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRendererEngine.php
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractRendererEngine;
|
||||
use Symfony\Component\Form\FormViewInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererEngineInterface
|
||||
{
|
||||
/**
|
||||
* @var \Twig_Environment
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
/**
|
||||
* @var \Twig_Template
|
||||
*/
|
||||
private $template;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setEnvironment(\Twig_Environment $environment)
|
||||
{
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderBlock(FormViewInterface $view, $resource, $block, array $variables = array())
|
||||
{
|
||||
$cacheKey = $view->getVar(self::CACHE_KEY_VAR);
|
||||
|
||||
$context = $this->environment->mergeGlobals($variables);
|
||||
|
||||
ob_start();
|
||||
|
||||
// By contract,This method can only be called after getting the resource
|
||||
// (which is passed to the method). Getting a resource for the first time
|
||||
// (with an empty cache) is guaranteed to invoke loadResourcesFromTheme(),
|
||||
// where the property $template is initialized.
|
||||
|
||||
// We do not call renderBlock here to avoid too many nested level calls
|
||||
// (XDebug limits the level to 100 by default)
|
||||
$this->template->displayBlock($block, $context, $this->resources[$cacheKey]);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the cache with the resource for a given block name.
|
||||
*
|
||||
* This implementation eagerly loads all blocks of the themes assigned to the given view
|
||||
* and all of its ancestors views. This is necessary, because Twig receives the
|
||||
* list of blocks later. At that point, all blocks must already be loaded, for the
|
||||
* case that the function "block()" is used in the Twig template.
|
||||
*
|
||||
* @see getResourceForBlock()
|
||||
*
|
||||
* @param string $cacheKey The cache key of the form view.
|
||||
* @param FormViewInterface $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
protected function loadResourceForBlock($cacheKey, FormViewInterface $view, $block)
|
||||
{
|
||||
// The caller guarantees that $this->resources[$cacheKey][$block] is
|
||||
// not set, but it doesn't have to check whether $this->resources[$cacheKey]
|
||||
// is set. If $this->resources[$cacheKey] is set, all themes for this
|
||||
// $cacheKey are already loaded (due to the eager population, see doc comment).
|
||||
if (isset($this->resources[$cacheKey])) {
|
||||
// As said in the previous, the caller guarantees that
|
||||
// $this->resources[$cacheKey][$block] is not set. Since the themes are
|
||||
// already loaded, it can only be a non-existing block.
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recursively try to find the block in the themes assigned to $view,
|
||||
// then of its parent view, then of the parent view of the parent and so on.
|
||||
// When the root view is reached in this recursion, also the default
|
||||
// themes are taken into account.
|
||||
|
||||
// Check each theme whether it contains the searched block
|
||||
if (isset($this->themes[$cacheKey])) {
|
||||
for ($i = count($this->themes[$cacheKey]) - 1; $i >= 0; --$i) {
|
||||
$this->loadResourcesFromTheme($cacheKey, $this->themes[$cacheKey][$i]);
|
||||
// CONTINUE LOADING (see doc comment)
|
||||
}
|
||||
}
|
||||
|
||||
// Check the default themes once we reach the root view without success
|
||||
if (!$view->hasParent()) {
|
||||
for ($i = count($this->defaultThemes) - 1; $i >= 0; --$i) {
|
||||
$this->loadResourcesFromTheme($cacheKey, $this->defaultThemes[$i]);
|
||||
// CONTINUE LOADING (see doc comment)
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed with the themes of the parent view
|
||||
if ($view->hasParent()) {
|
||||
$parentCacheKey = $view->getParent()->getVar(self::CACHE_KEY_VAR);
|
||||
|
||||
if (!isset($this->resources[$parentCacheKey])) {
|
||||
$this->loadResourceForBlock($parentCacheKey, $view->getParent(), $block);
|
||||
}
|
||||
|
||||
// EAGER CACHE POPULATION (see doc comment)
|
||||
foreach ($this->resources[$parentCacheKey] as $blockName => $resource) {
|
||||
if (!isset($this->resources[$cacheKey][$blockName])) {
|
||||
$this->resources[$cacheKey][$blockName] = $resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Even though we loaded the themes, it can happen that none of them
|
||||
// contains the searched block
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
// Cache that we didn't find anything to speed up further accesses
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
}
|
||||
|
||||
return false !== $this->resources[$cacheKey][$block];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the resources for all blocks in a theme.
|
||||
*
|
||||
* @param string $cacheKey The cache key for storing the resource.
|
||||
* @param mixed $theme The theme to load the block from. This parameter
|
||||
* is passed by reference, because it might be necessary
|
||||
* to initialize the theme first. Any changes made to
|
||||
* this variable will be kept and be available upon
|
||||
* further calls to this method using the same theme.
|
||||
*/
|
||||
protected function loadResourcesFromTheme($cacheKey, &$theme)
|
||||
{
|
||||
if (!$theme instanceof \Twig_Template) {
|
||||
/* @var \Twig_Template $theme */
|
||||
$theme = $this->environment->loadTemplate($theme);
|
||||
}
|
||||
|
||||
if (null === $this->template) {
|
||||
// Store the first \Twig_Template instance that we find so that
|
||||
// we can call displayBlock() later on. It doesn't matter *which*
|
||||
// template we use for that, since we pass the used blocks manually
|
||||
// anyway.
|
||||
$this->template = $theme;
|
||||
}
|
||||
|
||||
// Use a separate variable for the inheritance traversal, because
|
||||
// theme is a reference and we don't want to change it.
|
||||
$currentTheme = $theme;
|
||||
|
||||
// The do loop takes care of template inheritance.
|
||||
// Add blocks from all templates in the inheritance tree, but avoid
|
||||
// overriding blocks already set.
|
||||
do {
|
||||
foreach ($currentTheme->getBlocks() as $block => $blockData) {
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
// The resource given back is the key to the bucket that
|
||||
// contains this block.
|
||||
$this->resources[$cacheKey][$block] = $blockData;
|
||||
}
|
||||
}
|
||||
} while (false !== $currentTheme = $currentTheme->getParent(array()));
|
||||
}
|
||||
}
|
27
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRendererEngineInterface.php
vendored
Normal file
27
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRendererEngineInterface.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Form;
|
||||
|
||||
use Symfony\Component\Form\FormRendererEngineInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface TwigRendererEngineInterface extends FormRendererEngineInterface
|
||||
{
|
||||
/**
|
||||
* Sets Twig's environment.
|
||||
*
|
||||
* @param \Twig_Environment $environment
|
||||
*/
|
||||
public function setEnvironment(\Twig_Environment $environment);
|
||||
}
|
27
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRendererInterface.php
vendored
Normal file
27
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Form/TwigRendererInterface.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Form;
|
||||
|
||||
use Symfony\Component\Form\FormRendererInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface TwigRendererInterface extends FormRendererInterface
|
||||
{
|
||||
/**
|
||||
* Sets Twig's environment.
|
||||
*
|
||||
* @param \Twig_Environment $environment
|
||||
*/
|
||||
public function setEnvironment(\Twig_Environment $environment);
|
||||
}
|
@ -30,7 +30,7 @@ class FormThemeNode extends \Twig_Node
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('echo $this->env->getExtension(\'form\')->setTheme(')
|
||||
->write('$this->env->getExtension(\'form\')->renderer->setTheme(')
|
||||
->subcompile($this->getNode('form'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('resources'))
|
||||
|
@ -12,6 +12,8 @@
|
||||
namespace Symfony\Bridge\Twig\Tests\Extension;
|
||||
|
||||
use Symfony\Bridge\Twig\Extension\FormExtension;
|
||||
use Symfony\Bridge\Twig\Form\TwigRenderer;
|
||||
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator;
|
||||
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader;
|
||||
@ -20,6 +22,9 @@ use Symfony\Component\Form\Tests\AbstractDivLayoutTest;
|
||||
|
||||
class FormExtensionDivLayoutTest extends AbstractDivLayoutTest
|
||||
{
|
||||
/**
|
||||
* @var FormExtension
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
protected function setUp()
|
||||
@ -42,20 +47,23 @@ class FormExtensionDivLayoutTest extends AbstractDivLayoutTest
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$loader = new StubFilesystemLoader(array(
|
||||
__DIR__.'/../../../../../../src/Symfony/Bridge/Twig/Resources/views/Form',
|
||||
__DIR__,
|
||||
));
|
||||
|
||||
$this->extension = new FormExtension($this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array(
|
||||
$rendererEngine = new TwigRendererEngine(array(
|
||||
'form_div_layout.html.twig',
|
||||
'custom_widgets.html.twig',
|
||||
));
|
||||
$renderer = new TwigRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'));
|
||||
|
||||
$this->extension = new FormExtension($renderer);
|
||||
|
||||
$loader = new StubFilesystemLoader(array(
|
||||
__DIR__.'/../../Resources/views/Form',
|
||||
__DIR__,
|
||||
));
|
||||
|
||||
$environment = new \Twig_Environment($loader, array('strict_variables' => true));
|
||||
$environment->addExtension($this->extension);
|
||||
$environment->addExtension(new TranslationExtension(new StubTranslator()));
|
||||
$environment->addGlobal('global', '');
|
||||
$environment->addExtension($this->extension);
|
||||
|
||||
$this->extension->initRuntime($environment);
|
||||
}
|
||||
@ -99,37 +107,37 @@ class FormExtensionDivLayoutTest extends AbstractDivLayoutTest
|
||||
|
||||
protected function renderEnctype(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderEnctype($view);
|
||||
return (string) $this->extension->renderer->renderEnctype($view);
|
||||
}
|
||||
|
||||
protected function renderLabel(FormView $view, $label = null, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderLabel($view, $label, $vars);
|
||||
return (string) $this->extension->renderer->renderLabel($view, $label, $vars);
|
||||
}
|
||||
|
||||
protected function renderErrors(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderErrors($view);
|
||||
return (string) $this->extension->renderer->renderErrors($view);
|
||||
}
|
||||
|
||||
protected function renderWidget(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderWidget($view, $vars);
|
||||
return (string) $this->extension->renderer->renderWidget($view, $vars);
|
||||
}
|
||||
|
||||
protected function renderRow(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderRow($view, $vars);
|
||||
return (string) $this->extension->renderer->renderRow($view, $vars);
|
||||
}
|
||||
|
||||
protected function renderRest(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderRest($view, $vars);
|
||||
return (string) $this->extension->renderer->renderRest($view, $vars);
|
||||
}
|
||||
|
||||
protected function setTheme(FormView $view, array $themes)
|
||||
{
|
||||
$this->extension->setTheme($view, $themes);
|
||||
$this->extension->renderer->setTheme($view, $themes);
|
||||
}
|
||||
|
||||
public static function themeBlockInheritanceProvider()
|
||||
|
@ -12,6 +12,8 @@
|
||||
namespace Symfony\Bridge\Twig\Tests\Extension;
|
||||
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Bridge\Twig\Form\TwigRenderer;
|
||||
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
|
||||
use Symfony\Bridge\Twig\Extension\FormExtension;
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
use Symfony\Component\Form\Tests\AbstractTableLayoutTest;
|
||||
@ -20,6 +22,9 @@ use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader;
|
||||
|
||||
class FormExtensionTableLayoutTest extends AbstractTableLayoutTest
|
||||
{
|
||||
/**
|
||||
* @var FormExtension
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
protected function setUp()
|
||||
@ -42,20 +47,23 @@ class FormExtensionTableLayoutTest extends AbstractTableLayoutTest
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$loader = new StubFilesystemLoader(array(
|
||||
__DIR__.'/../../../../../../src/Symfony/Bridge/Twig/Resources/views/Form',
|
||||
__DIR__,
|
||||
));
|
||||
|
||||
$this->extension = new FormExtension($this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array(
|
||||
$rendererEngine = new TwigRendererEngine(array(
|
||||
'form_table_layout.html.twig',
|
||||
'custom_widgets.html.twig',
|
||||
));
|
||||
$renderer = new TwigRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'));
|
||||
|
||||
$this->extension = new FormExtension($renderer);
|
||||
|
||||
$loader = new StubFilesystemLoader(array(
|
||||
__DIR__.'/../../Resources/views/Form',
|
||||
__DIR__,
|
||||
));
|
||||
|
||||
$environment = new \Twig_Environment($loader, array('strict_variables' => true));
|
||||
$environment->addExtension($this->extension);
|
||||
$environment->addExtension(new TranslationExtension(new StubTranslator()));
|
||||
$environment->addGlobal('global', '');
|
||||
$environment->addExtension($this->extension);
|
||||
|
||||
$this->extension->initRuntime($environment);
|
||||
}
|
||||
@ -69,36 +77,36 @@ class FormExtensionTableLayoutTest extends AbstractTableLayoutTest
|
||||
|
||||
protected function renderEnctype(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderEnctype($view);
|
||||
return (string) $this->extension->renderer->renderEnctype($view);
|
||||
}
|
||||
|
||||
protected function renderLabel(FormView $view, $label = null, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderLabel($view, $label, $vars);
|
||||
return (string) $this->extension->renderer->renderLabel($view, $label, $vars);
|
||||
}
|
||||
|
||||
protected function renderErrors(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderErrors($view);
|
||||
return (string) $this->extension->renderer->renderErrors($view);
|
||||
}
|
||||
|
||||
protected function renderWidget(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderWidget($view, $vars);
|
||||
return (string) $this->extension->renderer->renderWidget($view, $vars);
|
||||
}
|
||||
|
||||
protected function renderRow(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderRow($view, $vars);
|
||||
return (string) $this->extension->renderer->renderRow($view, $vars);
|
||||
}
|
||||
|
||||
protected function renderRest(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderRest($view, $vars);
|
||||
return (string) $this->extension->renderer->renderRest($view, $vars);
|
||||
}
|
||||
|
||||
protected function setTheme(FormView $view, array $themes)
|
||||
{
|
||||
$this->extension->setTheme($view, $themes);
|
||||
$this->extension->renderer->setTheme($view, $themes);
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class FormThemeTest extends TestCase
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'echo $this->env->getExtension(\'form\')->setTheme(%s, array(0 => "tpl1", 1 => "tpl2"));',
|
||||
'$this->env->getExtension(\'form\')->renderer->setTheme(%s, array(0 => "tpl1", 1 => "tpl2"));',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
@ -67,7 +67,7 @@ class FormThemeTest extends TestCase
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'echo $this->env->getExtension(\'form\')->setTheme(%s, "tpl1");',
|
||||
'$this->env->getExtension(\'form\')->renderer->setTheme(%s, "tpl1");',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector as BaseRequestDataCollector;
|
||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
||||
|
||||
/**
|
||||
* RequestDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RequestDataCollector extends BaseRequestDataCollector
|
||||
{
|
||||
protected $controllers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->controllers = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
parent::collect($request, $response, $exception);
|
||||
|
||||
$this->data['controller'] = 'n/a';
|
||||
|
||||
if (isset($this->controllers[$request])) {
|
||||
$controller = $this->controllers[$request];
|
||||
if (is_array($controller)) {
|
||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
$this->data['controller'] = array(
|
||||
'class' => get_class($controller[0]),
|
||||
'method' => $controller[1],
|
||||
'file' => $r->getFilename(),
|
||||
'line' => $r->getStartLine(),
|
||||
);
|
||||
} elseif ($controller instanceof \Closure) {
|
||||
$this->data['controller'] = 'Closure';
|
||||
} else {
|
||||
$this->data['controller'] = (string) $controller ?: 'n/a';
|
||||
}
|
||||
unset($this->controllers[$request]);
|
||||
}
|
||||
}
|
||||
|
||||
public function onKernelController(FilterControllerEvent $event)
|
||||
{
|
||||
$this->controllers[$event->getRequest()] = $event->getController();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRoute()
|
||||
{
|
||||
return isset($this->data['request_attributes']['_route']) ? $this->data['request_attributes']['_route'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRouteParams()
|
||||
{
|
||||
return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getController()
|
||||
{
|
||||
return $this->data['controller'];
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
<parameters>
|
||||
<parameter key="data_collector.config.class">Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector</parameter>
|
||||
<parameter key="data_collector.request.class">Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector</parameter>
|
||||
<parameter key="data_collector.request.class">Symfony\Component\HttpKernel\DataCollector\RequestDataCollector</parameter>
|
||||
<parameter key="data_collector.exception.class">Symfony\Component\HttpKernel\DataCollector\ExceptionDataCollector</parameter>
|
||||
<parameter key="data_collector.events.class">Symfony\Component\HttpKernel\DataCollector\EventDataCollector</parameter>
|
||||
<parameter key="data_collector.logger.class">Symfony\Component\HttpKernel\DataCollector\LoggerDataCollector</parameter>
|
||||
@ -22,7 +22,7 @@
|
||||
</service>
|
||||
|
||||
<service id="data_collector.request" class="%data_collector.request.class%">
|
||||
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<tag name="data_collector" template="WebProfilerBundle:Collector:request" id="request" priority="255" />
|
||||
</service>
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
<parameter key="templating.helper.code.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\CodeHelper</parameter>
|
||||
<parameter key="templating.helper.translator.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper</parameter>
|
||||
<parameter key="templating.helper.form.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper</parameter>
|
||||
<parameter key="templating.form.engine.class">Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine</parameter>
|
||||
<parameter key="templating.form.renderer.class">Symfony\Component\Form\FormRenderer</parameter>
|
||||
<parameter key="templating.globals.class">Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables</parameter>
|
||||
<parameter key="templating.asset.path_package.class">Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage</parameter>
|
||||
<parameter key="templating.asset.url_package.class">Symfony\Component\Templating\Asset\UrlPackage</parameter>
|
||||
@ -96,11 +98,19 @@
|
||||
|
||||
<service id="templating.helper.form" class="%templating.helper.form.class%">
|
||||
<tag name="templating.helper" alias="form" />
|
||||
<argument type="service" id="templating.form.renderer" />
|
||||
</service>
|
||||
|
||||
<service id="templating.form.engine" class="%templating.form.engine.class%" public="false">
|
||||
<argument type="service" id="templating.engine.php" />
|
||||
<argument type="service" id="form.csrf_provider" on-invalid="null" />
|
||||
<argument>%templating.helper.form.resources%</argument>
|
||||
</service>
|
||||
|
||||
<service id="templating.form.renderer" class="%templating.form.renderer.class%" public="false">
|
||||
<argument type="service" id="templating.form.engine" />
|
||||
<argument type="service" id="form.csrf_provider" on-invalid="null" />
|
||||
</service>
|
||||
|
||||
<service id="templating.globals" class="%templating.globals.class%">
|
||||
<argument type="service" id="service_container" />
|
||||
</service>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<input type="checkbox"
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php if ($value): ?> value="<?php echo $view->escape($value) ?>"<?php endif ?>
|
||||
<?php if ($checked): ?> checked="checked"<?php endif ?>
|
||||
/>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('choice_widget_options') ?>
|
||||
<?php echo $view['form']->block('choice_widget_options') ?>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php if ($expanded): ?>
|
||||
<?php echo $view['form']->renderBlock('choice_widget_expanded') ?>
|
||||
<?php echo $view['form']->block('choice_widget_expanded') ?>
|
||||
<?php else: ?>
|
||||
<?php echo $view['form']->renderBlock('choice_widget_collapsed') ?>
|
||||
<?php echo $view['form']->block('choice_widget_collapsed') ?>
|
||||
<?php endif ?>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<select
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
|
||||
>
|
||||
<?php if (null !== $empty_value): ?><option value=""><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>
|
||||
<?php if (count($preferred_choices) > 0): ?>
|
||||
<?php echo $view['form']->renderBlock('choice_widget_options', array('options' => $preferred_choices)) ?>
|
||||
<?php echo $view['form']->block('choice_widget_options', array('options' => $preferred_choices)) ?>
|
||||
<?php if (count($choices) > 0 && null !== $separator): ?>
|
||||
<option disabled="disabled"><?php echo $separator ?></option>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->renderBlock('choice_widget_options', array('options' => $choices)) ?>
|
||||
<?php echo $view['form']->block('choice_widget_options', array('options' => $choices)) ?>
|
||||
</select>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<?php foreach ($form as $child): ?>
|
||||
<?php echo $view['form']->widget($child) ?>
|
||||
<?php echo $view['form']->label($child) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('widget_container_attributes') ?>
|
||||
<?php echo $view['form']->block('widget_container_attributes') ?>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single_text'): ?>
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple'); ?>
|
||||
<?php echo $view['form']->block('form_widget_simple'); ?>
|
||||
<?php else: ?>
|
||||
<div <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<?php echo str_replace(array('{{ year }}', '{{ month }}', '{{ day }}'), array(
|
||||
$view['form']->widget($form['year']),
|
||||
$view['form']->widget($form['month']),
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single_text'): ?>
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple'); ?>
|
||||
<?php echo $view['form']->block('form_widget_simple'); ?>
|
||||
<?php else: ?>
|
||||
<div <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<?php echo $view['form']->widget($form['date']).' '.$view['form']->widget($form['time']) ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : 'email')) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : 'email')) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_enctype') ?>
|
||||
<?php echo $view['form']->block('form_enctype') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_errors') ?>
|
||||
<?php echo $view['form']->block('form_errors') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_label') ?>
|
||||
<?php echo $view['form']->block('form_label') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_rest') ?>
|
||||
<?php echo $view['form']->block('form_rest') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_row') ?>
|
||||
<?php echo $view['form']->block('form_row') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_rows') ?>
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple') ?>
|
||||
<?php echo $view['form']->block('form_widget_simple') ?>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php if ($compound): ?>
|
||||
<?php echo $view['form']->renderBlock('form_widget_compound')?>
|
||||
<?php echo $view['form']->block('form_widget_compound')?>
|
||||
<?php else: ?>
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple')?>
|
||||
<?php echo $view['form']->block('form_widget_simple')?>
|
||||
<?php endif ?>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<?php if (!$form->hasParent() && $errors): ?>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
@ -6,6 +6,6 @@
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->renderBlock('form_rows') ?>
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
<?php echo $view['form']->rest($form) ?>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<input
|
||||
type="<?php echo isset($type) ? $view->escape($type) : 'text' ?>"
|
||||
<?php if (!empty($value)): ?>value="<?php echo $view->escape($value) ?>"<?php endif ?>
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
/>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "number")) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "number")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo str_replace('{{ widget }}', $view['form']->renderBlock('form_widget_simple'), $money_pattern) ?>
|
||||
<?php echo str_replace('{{ widget }}', $view['form']->block('form_widget_simple'), $money_pattern) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "password")) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "password")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> %
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> %
|
||||
|
@ -1,5 +1,5 @@
|
||||
<input type="radio"
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($checked): ?> checked="checked"<?php endif ?>
|
||||
/>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_rows') ?>
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "search")) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "search")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<textarea <?php echo $view['form']->renderBlock('widget_attributes') ?>><?php echo $view->escape($value) ?></textarea>
|
||||
<textarea <?php echo $view['form']->block('widget_attributes') ?>><?php echo $view->escape($value) ?></textarea>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single_text'): ?>
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple'); ?>
|
||||
<?php echo $view['form']->block('form_widget_simple'); ?>
|
||||
<?php else: ?>
|
||||
<div <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<?php
|
||||
// There should be no spaces between the colons and the widgets, that's why
|
||||
// this block is written in a single PHP tag
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "url")) ?>
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "url")) ?>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<table <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
|
||||
<table <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<?php if (!$form->hasParent()): ?>
|
||||
<?php echo $view['form']->errors($form) ?>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->renderBlock('form_rows') ?>
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
<?php echo $view['form']->rest($form) ?>
|
||||
</table>
|
||||
|
@ -12,8 +12,9 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
|
||||
|
||||
use Symfony\Component\Templating\Helper\Helper;
|
||||
use Symfony\Component\Form\FormRendererInterface;
|
||||
use Symfony\Component\Form\FormViewInterface;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
@ -27,46 +28,35 @@ use Symfony\Component\Form\Util\FormUtil;
|
||||
*/
|
||||
class FormHelper extends Helper
|
||||
{
|
||||
protected $engine;
|
||||
|
||||
protected $csrfProvider;
|
||||
|
||||
protected $varStack;
|
||||
|
||||
protected $context;
|
||||
|
||||
protected $resources;
|
||||
|
||||
protected $themes;
|
||||
|
||||
protected $templates;
|
||||
/**
|
||||
* @var FormRendererInterface
|
||||
*/
|
||||
private $renderer;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EngineInterface $engine The templating engine
|
||||
* @param CsrfProviderInterface $csrfProvider The CSRF provider
|
||||
* @param array $resources An array of theme names
|
||||
* @param FormRendererInterface $renderer
|
||||
*/
|
||||
public function __construct(EngineInterface $engine, CsrfProviderInterface $csrfProvider = null, array $resources = array())
|
||||
public function __construct(FormRendererInterface $renderer)
|
||||
{
|
||||
$this->engine = $engine;
|
||||
$this->csrfProvider = $csrfProvider;
|
||||
$this->resources = $resources;
|
||||
$this->varStack = array();
|
||||
$this->context = array();
|
||||
$this->templates = array();
|
||||
$this->themes = array();
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'form';
|
||||
}
|
||||
|
||||
public function isChoiceGroup($label)
|
||||
{
|
||||
return FormUtil::isChoiceGroup($label);
|
||||
return $this->renderer->isChoiceGroup($label);
|
||||
}
|
||||
|
||||
public function isChoiceSelected(FormView $view, ChoiceView $choice)
|
||||
public function isChoiceSelected(FormViewInterface $view, ChoiceView $choice)
|
||||
{
|
||||
return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value'));
|
||||
return $this->renderer->isChoiceSelected($view, $choice);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,13 +64,12 @@ class FormHelper extends Helper
|
||||
*
|
||||
* The theme format is "<Bundle>:<Controller>".
|
||||
*
|
||||
* @param FormView $view A FormView instance
|
||||
* @param FormViewInterface $view A FormViewInterface instance
|
||||
* @param string|array $themes A theme or an array of theme
|
||||
*/
|
||||
public function setTheme(FormView $view, $themes)
|
||||
public function setTheme(FormViewInterface $view, $themes)
|
||||
{
|
||||
$this->themes[$view->getVar('id')] = (array) $themes;
|
||||
$this->templates = array();
|
||||
$this->renderer->setTheme($view, $themes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,13 +79,13 @@ class FormHelper extends Helper
|
||||
*
|
||||
* <form action="..." method="post" <?php echo $view['form']->enctype() ?>>
|
||||
*
|
||||
* @param FormView $view The view for which to render the encoding type
|
||||
* @param FormViewInterface $view The view for which to render the encoding type
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function enctype(FormView $view)
|
||||
public function enctype(FormViewInterface $view)
|
||||
{
|
||||
return $this->renderSection($view, 'enctype');
|
||||
return $this->renderer->renderEnctype($view);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,70 +101,95 @@ class FormHelper extends Helper
|
||||
*
|
||||
* <?php echo view['form']->widget(array('separator' => '+++++)) ?>
|
||||
*
|
||||
* @param FormView $view The view for which to render the widget
|
||||
* @param array $variables Additional variables passed to the template
|
||||
* @param FormViewInterface $view The view for which to render the widget
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function widget(FormView $view, array $variables = array())
|
||||
public function widget(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'widget', $variables);
|
||||
return $this->renderer->renderWidget($view, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the entire form field "row".
|
||||
*
|
||||
* @param FormView $view The view for which to render the row
|
||||
* @param array $variables Additional variables passed to the template
|
||||
* @param FormViewInterface $view The view for which to render the row
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function row(FormView $view, array $variables = array())
|
||||
public function row(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'row', $variables);
|
||||
return $this->renderer->renderRow($view, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the label of the given view.
|
||||
*
|
||||
* @param FormView $view The view for which to render the label
|
||||
* @param string $label The label
|
||||
* @param array $variables Additional variables passed to the template
|
||||
* @param FormViewInterface $view The view for which to render the label
|
||||
* @param string $label The label
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function label(FormView $view, $label = null, array $variables = array())
|
||||
public function label(FormViewInterface $view, $label = null, array $variables = array())
|
||||
{
|
||||
if ($label !== null) {
|
||||
$variables += array('label' => $label);
|
||||
}
|
||||
|
||||
return $this->renderSection($view, 'label', $variables);
|
||||
return $this->renderer->renderLabel($view, $label, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the errors of the given view.
|
||||
*
|
||||
* @param FormView $view The view to render the errors for
|
||||
* @param FormViewInterface $view The view to render the errors for
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function errors(FormView $view)
|
||||
public function errors(FormViewInterface $view)
|
||||
{
|
||||
return $this->renderSection($view, 'errors');
|
||||
return $this->renderer->renderErrors($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders views which have not already been rendered.
|
||||
*
|
||||
* @param FormView $view The parent view
|
||||
* @param array $variables An array of variables
|
||||
* @param FormViewInterface $view The parent view
|
||||
* @param array $variables An array of variables
|
||||
*
|
||||
* @return string The html markup
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function rest(FormView $view, array $variables = array())
|
||||
public function rest(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'rest', $variables);
|
||||
return $this->renderer->renderRest($view, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of {@link block()}
|
||||
*
|
||||
* @param string $block The name of the block to render.
|
||||
* @param array $variables The variable to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link block()} instead.
|
||||
*/
|
||||
public function renderBlock($block, array $variables = array())
|
||||
{
|
||||
return $this->block($block, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a block of the template.
|
||||
*
|
||||
* @param string $block The name of the block to render.
|
||||
* @param array $variables The variable to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function block($block, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderBlock($block, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,166 +214,16 @@ class FormHelper extends Helper
|
||||
* @param string $intention The intention of the protected action
|
||||
*
|
||||
* @return string A CSRF token
|
||||
*
|
||||
* @throws \BadMethodCallException When no CSRF provider was injected in the constructor.
|
||||
*/
|
||||
public function csrfToken($intention)
|
||||
{
|
||||
if (!$this->csrfProvider instanceof CsrfProviderInterface) {
|
||||
throw new \BadMethodCallException('CSRF token can only be generated if a CsrfProviderInterface is injected in the constructor.');
|
||||
}
|
||||
|
||||
return $this->csrfProvider->generateCsrfToken($intention);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a template.
|
||||
*
|
||||
* 1. This function first looks for a block named "_<view id>_<section>",
|
||||
* 2. if such a block is not found the function will look for a block named
|
||||
* "<type name>_<section>",
|
||||
* 3. the type name is recursively replaced by the parent type name until a
|
||||
* corresponding block is found
|
||||
*
|
||||
* @param FormView $view The form view
|
||||
* @param string $section The section to render (i.e. 'row', 'widget', 'label', ...)
|
||||
* @param array $variables Additional variables
|
||||
*
|
||||
* @return string The html markup
|
||||
*
|
||||
* @throws FormException if no template block exists to render the given section of the view
|
||||
*/
|
||||
protected function renderSection(FormView $view, $section, array $variables = array())
|
||||
{
|
||||
$mainTemplate = in_array($section, array('row', 'widget'));
|
||||
if ($mainTemplate && $view->isRendered()) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$template = null;
|
||||
|
||||
$custom = '_'.$view->getVar('id');
|
||||
$rendering = $custom.$section;
|
||||
|
||||
if (isset($this->varStack[$rendering])) {
|
||||
$typeIndex = $this->varStack[$rendering]['typeIndex'] - 1;
|
||||
$types = $this->varStack[$rendering]['types'];
|
||||
$variables = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
|
||||
} else {
|
||||
$types = $view->getVar('types');
|
||||
$types[] = $view->getVar('full_block_name');
|
||||
$typeIndex = count($types) - 1;
|
||||
$variables = array_replace_recursive($view->getVars(), $variables);
|
||||
$this->varStack[$rendering]['types'] = $types;
|
||||
}
|
||||
|
||||
$this->varStack[$rendering]['variables'] = $variables;
|
||||
|
||||
do {
|
||||
$types[$typeIndex] .= '_'.$section;
|
||||
$template = $this->lookupTemplate($view, $types[$typeIndex]);
|
||||
|
||||
if ($template) {
|
||||
|
||||
$this->varStack[$rendering]['typeIndex'] = $typeIndex;
|
||||
|
||||
$this->context[] = array(
|
||||
'variables' => $variables,
|
||||
'view' => $view,
|
||||
);
|
||||
|
||||
$html = $this->engine->render($template, $variables);
|
||||
|
||||
array_pop($this->context);
|
||||
unset($this->varStack[$rendering]);
|
||||
|
||||
if ($mainTemplate) {
|
||||
$view->setRendered();
|
||||
}
|
||||
|
||||
return trim($html);
|
||||
}
|
||||
} while (--$typeIndex >= 0);
|
||||
|
||||
throw new FormException(sprintf(
|
||||
'Unable to render the form as none of the following blocks exist: "%s".',
|
||||
implode('", "', array_reverse($types))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a block from a form element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $variables Additional variables (those would override the current context)
|
||||
*
|
||||
* @throws FormException if the block is not found
|
||||
* @throws FormException if the method is called out of a form element (no context)
|
||||
*/
|
||||
public function renderBlock($name, $variables = array())
|
||||
{
|
||||
if (0 == count($this->context)) {
|
||||
throw new FormException(sprintf('This method should only be called while rendering a form element.', $name));
|
||||
}
|
||||
|
||||
$context = end($this->context);
|
||||
|
||||
$template = $this->lookupTemplate($context['view'], $name);
|
||||
|
||||
if (false === $template) {
|
||||
throw new FormException(sprintf('No block "%s" found while rendering the form.', $name));
|
||||
}
|
||||
|
||||
$variables = array_replace_recursive($context['variables'], $variables);
|
||||
|
||||
return trim($this->engine->render($template, $variables));
|
||||
return $this->renderer->renderCsrfToken($intention);
|
||||
}
|
||||
|
||||
public function humanize($text)
|
||||
{
|
||||
return ucfirst(trim(strtolower(preg_replace('/[_\s]+/', ' ', $text))));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the template to use to render the block
|
||||
*
|
||||
* @param FormView $view The form view
|
||||
* @param string $block The name of the block
|
||||
*
|
||||
* @return string|Boolean The template logical name or false when no template is found
|
||||
*/
|
||||
protected function lookupTemplate(FormView $view, $block)
|
||||
{
|
||||
$file = $block.'.html.php';
|
||||
$id = $view->getVar('id');
|
||||
|
||||
if (!isset($this->templates[$id][$block])) {
|
||||
$template = false;
|
||||
|
||||
$themes = $view->hasParent() ? array() : $this->resources;
|
||||
|
||||
if (isset($this->themes[$id])) {
|
||||
$themes = array_merge($themes, $this->themes[$id]);
|
||||
}
|
||||
|
||||
for ($i = count($themes) - 1; $i >= 0; --$i) {
|
||||
if ($this->engine->exists($templateName = $themes[$i].':'.$file)) {
|
||||
$template = $templateName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $template && $view->hasParent()) {
|
||||
$template = $this->lookupTemplate($view->getParent(), $block);
|
||||
}
|
||||
|
||||
$this->templates[$id][$block] = $template;
|
||||
}
|
||||
|
||||
return $this->templates[$id][$block];
|
||||
return $this->renderer->humanize($text);
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,11 @@ use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper;
|
||||
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Templating\PhpEngine;
|
||||
use Symfony\Component\Templating\Loader\FilesystemLoader;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\FormRenderer;
|
||||
use Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine;
|
||||
use Symfony\Component\Form\Tests\AbstractDivLayoutTest;
|
||||
|
||||
class FormHelperDivLayoutTest extends AbstractDivLayoutTest
|
||||
@ -26,6 +28,8 @@ class FormHelperDivLayoutTest extends AbstractDivLayoutTest
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
ini_set('xdebug.max_nesting_level', 120);
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$root = realpath(__DIR__.'/../../../Resources/views');
|
||||
@ -34,8 +38,10 @@ class FormHelperDivLayoutTest extends AbstractDivLayoutTest
|
||||
$loader = new FilesystemLoader(array());
|
||||
$engine = new PhpEngine($templateNameParser, $loader);
|
||||
$engine->addGlobal('global', '');
|
||||
$rendererEngine = new TemplatingRendererEngine($engine, array('FrameworkBundle:Form'));
|
||||
$renderer = new FormRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'));
|
||||
|
||||
$this->helper = new FormHelper($engine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array('FrameworkBundle:Form'));
|
||||
$this->helper = new FormHelper($renderer);
|
||||
|
||||
$engine->setHelpers(array(
|
||||
$this->helper,
|
||||
|
@ -16,9 +16,11 @@ use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\FormRenderer;
|
||||
use Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine;
|
||||
use Symfony\Component\Form\Tests\AbstractTableLayoutTest;
|
||||
use Symfony\Component\Templating\PhpEngine;
|
||||
use Symfony\Component\Templating\Loader\FilesystemLoader;
|
||||
use Symfony\Component\Form\Tests\AbstractTableLayoutTest;
|
||||
|
||||
class FormHelperTableLayoutTest extends AbstractTableLayoutTest
|
||||
{
|
||||
@ -34,11 +36,13 @@ class FormHelperTableLayoutTest extends AbstractTableLayoutTest
|
||||
$loader = new FilesystemLoader(array());
|
||||
$engine = new PhpEngine($templateNameParser, $loader);
|
||||
$engine->addGlobal('global', '');
|
||||
|
||||
$this->helper = new FormHelper($engine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array(
|
||||
$rendererEngine = new TemplatingRendererEngine($engine, array(
|
||||
'FrameworkBundle:Form',
|
||||
'FrameworkBundle:FormTable'
|
||||
));
|
||||
$renderer = new FormRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'));
|
||||
|
||||
$this->helper = new FormHelper($renderer);
|
||||
|
||||
$engine->setHelpers(array(
|
||||
$this->helper,
|
||||
|
@ -172,7 +172,7 @@ abstract class AbstractFactory implements SecurityFactoryInterface
|
||||
return $config['success_handler'];
|
||||
}
|
||||
|
||||
$successHandlerId = 'security.authentication.success_handler.'.$id;
|
||||
$successHandlerId = 'security.authentication.success_handler.'.$id.'.'.str_replace('-', '_', $this->getKey());
|
||||
|
||||
$successHandler = $container->setDefinition($successHandlerId, new DefinitionDecorator('security.authentication.success_handler'));
|
||||
$successHandler->replaceArgument(1, array_intersect_key($config, $this->defaultSuccessHandlerOptions));
|
||||
@ -187,7 +187,7 @@ abstract class AbstractFactory implements SecurityFactoryInterface
|
||||
return $config['failure_handler'];
|
||||
}
|
||||
|
||||
$id = 'security.authentication.failure_handler.'.$id;
|
||||
$id = 'security.authentication.failure_handler.'.$id.'.'.str_replace('-', '_', $this->getKey());
|
||||
|
||||
$failureHandler = $container->setDefinition($id, new DefinitionDecorator('security.authentication.failure_handler'));
|
||||
$failureHandler->replaceArgument(2, array_intersect_key($config, $this->defaultFailureHandlerOptions));
|
||||
|
@ -54,7 +54,7 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$definition = $container->getDefinition('abstract_listener.foo');
|
||||
$arguments = $definition->getArguments();
|
||||
$this->assertEquals(new Reference('security.authentication.failure_handler.foo'), $arguments['index_6']);
|
||||
$this->assertEquals(new Reference('security.authentication.failure_handler.foo.abstract_factory'), $arguments['index_6']);
|
||||
}
|
||||
|
||||
public function testDefaultSuccessHandler()
|
||||
@ -67,7 +67,7 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$definition = $container->getDefinition('abstract_listener.foo');
|
||||
$arguments = $definition->getArguments();
|
||||
$this->assertEquals(new Reference('security.authentication.success_handler.foo'), $arguments['index_5']);
|
||||
$this->assertEquals(new Reference('security.authentication.success_handler.foo.abstract_factory'), $arguments['index_5']);
|
||||
}
|
||||
|
||||
protected function callFactory($id, $config, $userProviderId, $defaultEntryPointId)
|
||||
@ -84,6 +84,11 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
->method('getListenerId')
|
||||
->will($this->returnValue('abstract_listener'))
|
||||
;
|
||||
$factory
|
||||
->expects($this->any())
|
||||
->method('getKey')
|
||||
->will($this->returnValue('abstract_factory'))
|
||||
;
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('auth_provider');
|
||||
|
@ -16,6 +16,8 @@
|
||||
<parameter key="twig.extension.routing.class">Symfony\Bridge\Twig\Extension\RoutingExtension</parameter>
|
||||
<parameter key="twig.extension.yaml.class">Symfony\Bridge\Twig\Extension\YamlExtension</parameter>
|
||||
<parameter key="twig.extension.form.class">Symfony\Bridge\Twig\Extension\FormExtension</parameter>
|
||||
<parameter key="twig.form.engine.class">Symfony\Bridge\Twig\Form\TwigRendererEngine</parameter>
|
||||
<parameter key="twig.form.renderer.class">Symfony\Bridge\Twig\Form\TwigRenderer</parameter>
|
||||
<parameter key="twig.translation.extractor.class">Symfony\Bridge\Twig\Translation\TwigExtractor</parameter>
|
||||
<parameter key="twig.exception_listener.class">Symfony\Component\HttpKernel\EventListener\ExceptionListener</parameter>
|
||||
</parameters>
|
||||
@ -75,10 +77,18 @@
|
||||
|
||||
<service id="twig.extension.form" class="%twig.extension.form.class%" public="false">
|
||||
<tag name="twig.extension" />
|
||||
<argument type="service" id="form.csrf_provider" on-invalid="null" />
|
||||
<argument type="service" id="twig.form.renderer" />
|
||||
</service>
|
||||
|
||||
<service id="twig.form.engine" class="%twig.form.engine.class%" public="false">
|
||||
<argument>%twig.form.resources%</argument>
|
||||
</service>
|
||||
|
||||
<service id="twig.form.renderer" class="%twig.form.renderer.class%" public="false">
|
||||
<argument type="service" id="twig.form.engine" />
|
||||
<argument type="service" id="form.csrf_provider" on-invalid="null" />
|
||||
</service>
|
||||
|
||||
<service id="twig.translation.extractor" class="%twig.translation.extractor.class%">
|
||||
<argument type="service" id="twig" />
|
||||
<tag name="translation.extractor" alias="twig" />
|
||||
|
@ -86,7 +86,7 @@
|
||||
margin-left: -1px;
|
||||
|
||||
bottom: 38px;
|
||||
border-bottom: 1px solid #fff;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.sf-toolbar-block .sf-toolbar-info:empty {
|
||||
@ -216,9 +216,9 @@
|
||||
}
|
||||
|
||||
.sf-toolbar-block .sf-toolbar-info {
|
||||
top: 38px;
|
||||
top: 39px;
|
||||
bottom: auto;
|
||||
border-top: 1px solid #fff;
|
||||
border-top-width: 0;
|
||||
border-bottom: 1px solid #bbb;
|
||||
}
|
||||
{% endif %}
|
||||
|
@ -13,4 +13,4 @@ CHANGELOG
|
||||
* added GenericEvent event class
|
||||
* added the possibility for subscribers to subscribe several times for the
|
||||
same event
|
||||
* added UnmodifiableEventDispatcher
|
||||
* added ImmutableEventDispatcher
|
||||
|
@ -16,7 +16,7 @@ namespace Symfony\Component\EventDispatcher;
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class UnmodifiableEventDispatcher implements EventDispatcherInterface
|
||||
class ImmutableEventDispatcher implements EventDispatcherInterface
|
||||
{
|
||||
/**
|
||||
* The proxied dispatcher.
|
@ -12,13 +12,13 @@
|
||||
namespace Symfony\Component\EventDispatcher\Tests;
|
||||
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\EventDispatcher\UnmodifiableEventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class UnmodifiableEventDispatcherTest extends \PHPUnit_Framework_TestCase
|
||||
class ImmutableEventDispatcherTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
@ -26,14 +26,14 @@ class UnmodifiableEventDispatcherTest extends \PHPUnit_Framework_TestCase
|
||||
private $innerDispatcher;
|
||||
|
||||
/**
|
||||
* @var UnmodifiableEventDispatcher
|
||||
* @var ImmutableEventDispatcher
|
||||
*/
|
||||
private $dispatcher;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->innerDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$this->dispatcher = new UnmodifiableEventDispatcher($this->innerDispatcher);
|
||||
$this->dispatcher = new ImmutableEventDispatcher($this->innerDispatcher);
|
||||
}
|
||||
|
||||
public function testDispatchDelegates()
|
@ -66,7 +66,7 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
return new self();
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
|
206
vendor/symfony/symfony/src/Symfony/Component/Form/AbstractRendererEngine.php
vendored
Normal file
206
vendor/symfony/symfony/src/Symfony/Component/Form/AbstractRendererEngine.php
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link FormRendererEngineInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
abstract class AbstractRendererEngine implements FormRendererEngineInterface
|
||||
{
|
||||
/**
|
||||
* The variable in {@link FormViewInterface} used as cache key.
|
||||
*/
|
||||
const CACHE_KEY_VAR = 'full_block_name';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $defaultThemes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $themes = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $resources = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $resourceHierarchyLevels = array();
|
||||
|
||||
/**
|
||||
* Creates a new renderer engine.
|
||||
*
|
||||
* @param array $defaultThemes The default themes. The type of these
|
||||
* themes is open to the implementation.
|
||||
*/
|
||||
public function __construct(array $defaultThemes = array())
|
||||
{
|
||||
$this->defaultThemes = $defaultThemes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTheme(FormViewInterface $view, $themes)
|
||||
{
|
||||
$cacheKey = $view->getVar(self::CACHE_KEY_VAR);
|
||||
|
||||
// Do not cast, as casting turns objects into arrays of properties
|
||||
$this->themes[$cacheKey] = is_array($themes) ? $themes : array($themes);
|
||||
|
||||
// Unset instead of resetting to an empty array, in order to allow
|
||||
// implementations (like TwigRendererEngine) to check whether $cacheKey
|
||||
// is set at all.
|
||||
unset($this->resources[$cacheKey]);
|
||||
unset($this->resourceHierarchyLevels[$cacheKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResourceForBlock(FormViewInterface $view, $block)
|
||||
{
|
||||
$cacheKey = $view->getVar(self::CACHE_KEY_VAR);
|
||||
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
$this->loadResourceForBlock($cacheKey, $view, $block);
|
||||
}
|
||||
|
||||
return $this->resources[$cacheKey][$block];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResourceForBlockHierarchy(FormViewInterface $view, array $blockHierarchy, $hierarchyLevel)
|
||||
{
|
||||
$cacheKey = $view->getVar(self::CACHE_KEY_VAR);
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
$this->loadResourceForBlockHierarchy($cacheKey, $view, $blockHierarchy, $hierarchyLevel);
|
||||
}
|
||||
|
||||
return $this->resources[$cacheKey][$block];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResourceHierarchyLevel(FormViewInterface $view, array $blockHierarchy, $hierarchyLevel)
|
||||
{
|
||||
$cacheKey = $view->getVar(self::CACHE_KEY_VAR);
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
$this->loadResourceForBlockHierarchy($cacheKey, $view, $blockHierarchy, $hierarchyLevel);
|
||||
}
|
||||
|
||||
// If $block was previously rendered loaded with loadTemplateForBlock(), the template
|
||||
// is cached but the hierarchy level is not. In this case, we know that the block
|
||||
// exists at this very hierarchy level, so we can just set it.
|
||||
if (!isset($this->resourceHierarchyLevels[$cacheKey][$block])) {
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $hierarchyLevel;
|
||||
}
|
||||
|
||||
return $this->resourceHierarchyLevels[$cacheKey][$block];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the cache with the resource for a given block name.
|
||||
*
|
||||
* @see getResourceForBlock()
|
||||
*
|
||||
* @param string $cacheKey The cache key of the form view.
|
||||
* @param FormViewInterface $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
abstract protected function loadResourceForBlock($cacheKey, FormViewInterface $view, $block);
|
||||
|
||||
/**
|
||||
* Loads the cache with the resource for a specific level of a block hierarchy.
|
||||
*
|
||||
* @see getResourceForBlockHierarchy()
|
||||
*
|
||||
* @param string $cacheKey The cache key used for storing the
|
||||
* resource.
|
||||
* @param FormViewInterface $view The form view for finding the applying
|
||||
* themes.
|
||||
* @param array $blockHierarchy The block hierarchy, with the most
|
||||
* specific block name at the end.
|
||||
* @param integer $hierarchyLevel The level in the block hierarchy that
|
||||
* should be loaded.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
private function loadResourceForBlockHierarchy($cacheKey, FormViewInterface $view, array $blockHierarchy, $hierarchyLevel)
|
||||
{
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
|
||||
// Try to find a template for that block
|
||||
if ($this->loadResourceForBlock($cacheKey, $view, $block)) {
|
||||
// If loadTemplateForBlock() returns true, it was able to populate the
|
||||
// cache. The only missing thing is to set the hierarchy level at which
|
||||
// the template was found.
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $hierarchyLevel;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($hierarchyLevel > 0) {
|
||||
$parentLevel = $hierarchyLevel - 1;
|
||||
$parentBlock = $blockHierarchy[$parentLevel];
|
||||
|
||||
// The next two if statements contain slightly duplicated code. This is by intention
|
||||
// and tries to avoid execution of unnecessary checks in order to increase performance.
|
||||
|
||||
if (isset($this->resources[$cacheKey][$parentBlock])) {
|
||||
// It may happen that the parent block is already loaded, but its level is not.
|
||||
// In this case, the parent block must have been loaded by loadResourceForBlock(),
|
||||
// which does not check the hierarchy of the block. Subsequently the block must have
|
||||
// been found directly on the parent level.
|
||||
if (!isset($this->resourceHierarchyLevels[$cacheKey][$parentBlock])) {
|
||||
$this->resourceHierarchyLevels[$cacheKey][$parentBlock] = $parentLevel;
|
||||
}
|
||||
|
||||
// Cache the shortcuts for further accesses
|
||||
$this->resources[$cacheKey][$block] = $this->resources[$cacheKey][$parentBlock];
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $this->resourceHierarchyLevels[$cacheKey][$parentBlock];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->loadResourceForBlockHierarchy($cacheKey, $view, $blockHierarchy, $parentLevel)) {
|
||||
// Cache the shortcuts for further accesses
|
||||
$this->resources[$cacheKey][$block] = $this->resources[$cacheKey][$parentBlock];
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $this->resourceHierarchyLevels[$cacheKey][$parentBlock];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the result for further accesses
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ CHANGELOG
|
||||
* ArrayToChoicesTransformer to ChoicesToValuesTransformer
|
||||
* ScalarToChoiceTransformer to ChoiceToValueTransformer
|
||||
to be consistent with the naming in ChoiceListInterface.
|
||||
* [BC BREAK] removed FormUtil::toArrayKey() and FormUtil::toArrayKeys().
|
||||
They were merged into ChoiceList and have no public equivalent anymore.
|
||||
* choice fields now throw a FormException if neither the "choices" nor the
|
||||
"choice_list" option is set
|
||||
@ -141,7 +140,7 @@ CHANGELOG
|
||||
* deprecated `hasChildren` in Form and FormBuilder in favor of `count`
|
||||
* FormBuilder now implements \IteratorAggregate
|
||||
* [BC BREAK] compound forms now always need a data mapper
|
||||
* FormBuilder now maintains the order when explicitely adding form builders as children
|
||||
* FormBuilder now maintains the order when explicitly adding form builders as children
|
||||
* ChoiceType now doesn't add the empty value anymore if the choices already contain an empty element
|
||||
* DateType, TimeType and DateTimeType now show empty values again if not required
|
||||
* [BC BREAK] fixed rendering of errors for DateType, BirthdayType and similar ones
|
||||
@ -172,4 +171,11 @@ CHANGELOG
|
||||
* ChoiceType now caches its created choice lists to improve performance
|
||||
* [BC BREAK] Rows of a collection field cannot be themed individually anymore. All rows in the collection
|
||||
field now have the same block names, which contains "entry" where it previously contained the row index.
|
||||
* [BC BREAK] When registering a type through the DI extension, the tag alias has to match the actual type name.
|
||||
* [BC BREAK] When registering a type through the DI extension, the tag alias has to match the actual type name.
|
||||
* added FormRendererInterface, FormRendererEngineInterface and implementations of these interfaces
|
||||
* [BC BREAK] removed the following methods from FormUtil:
|
||||
* `toArrayKey`
|
||||
* `toArrayKeys`
|
||||
* `isChoiceGroup`
|
||||
* `isChoiceSelected`
|
||||
* added method `block` to FormHelper and deprecated `renderBlock` instead
|
||||
|
@ -157,7 +157,7 @@ class ChoiceType extends AbstractType
|
||||
return $options['required'] ? null : '';
|
||||
};
|
||||
|
||||
$emptyValueFilter = function (Options $options, $emptyValue) {
|
||||
$emptyValueNormalizer = function (Options $options, $emptyValue) {
|
||||
if ($options['multiple'] || $options['expanded']) {
|
||||
// never use an empty value for these cases
|
||||
return null;
|
||||
@ -186,8 +186,8 @@ class ChoiceType extends AbstractType
|
||||
'compound' => $compound,
|
||||
));
|
||||
|
||||
$resolver->setFilters(array(
|
||||
'empty_value' => $emptyValueFilter,
|
||||
$resolver->setNormalizers(array(
|
||||
'empty_value' => $emptyValueNormalizer,
|
||||
));
|
||||
|
||||
$resolver->setAllowedTypes(array(
|
||||
|
@ -74,7 +74,7 @@ class CollectionType extends AbstractType
|
||||
*/
|
||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||
{
|
||||
$optionsFilter = function (Options $options, $value) {
|
||||
$optionsNormalizer = function (Options $options, $value) {
|
||||
$value['block_name'] = 'entry';
|
||||
|
||||
return $value;
|
||||
@ -89,8 +89,8 @@ class CollectionType extends AbstractType
|
||||
'options' => array(),
|
||||
));
|
||||
|
||||
$resolver->setFilters(array(
|
||||
'options' => $optionsFilter,
|
||||
$resolver->setNormalizers(array(
|
||||
'options' => $optionsNormalizer,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ class DateType extends AbstractType
|
||||
return $options['required'] ? null : '';
|
||||
};
|
||||
|
||||
$emptyValueFilter = function (Options $options, $emptyValue) use ($emptyValueDefault) {
|
||||
$emptyValueNormalizer = function (Options $options, $emptyValue) use ($emptyValueDefault) {
|
||||
if (is_array($emptyValue)) {
|
||||
$default = $emptyValueDefault($options);
|
||||
|
||||
@ -216,8 +216,8 @@ class DateType extends AbstractType
|
||||
'compound' => $compound,
|
||||
));
|
||||
|
||||
$resolver->setFilters(array(
|
||||
'empty_value' => $emptyValueFilter,
|
||||
$resolver->setNormalizers(array(
|
||||
'empty_value' => $emptyValueNormalizer,
|
||||
));
|
||||
|
||||
$resolver->setAllowedValues(array(
|
||||
|
@ -134,7 +134,7 @@ class TimeType extends AbstractType
|
||||
return $options['required'] ? null : '';
|
||||
};
|
||||
|
||||
$emptyValueFilter = function (Options $options, $emptyValue) use ($emptyValueDefault) {
|
||||
$emptyValueNormalizer = function (Options $options, $emptyValue) use ($emptyValueDefault) {
|
||||
if (is_array($emptyValue)) {
|
||||
$default = $emptyValueDefault($options);
|
||||
|
||||
@ -186,8 +186,8 @@ class TimeType extends AbstractType
|
||||
'compound' => $compound,
|
||||
));
|
||||
|
||||
$resolver->setFilters(array(
|
||||
'empty_value' => $emptyValueFilter,
|
||||
$resolver->setNormalizers(array(
|
||||
'empty_value' => $emptyValueNormalizer,
|
||||
));
|
||||
|
||||
$resolver->setAllowedValues(array(
|
||||
|
@ -46,7 +46,12 @@ class DependencyInjectionExtension implements FormExtensionInterface
|
||||
$type = $this->container->get($this->typeServiceIds[$name]);
|
||||
|
||||
if ($type->getName() !== $name) {
|
||||
throw new \InvalidArgumentException(sprintf('The type name specified for the service %s does not match the actual name', $this->typeServiceIds[$name]));
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('The type name specified for the service "%s" does not match the actual name. Expected "%s", given "%s"',
|
||||
$this->typeServiceIds[$name],
|
||||
$name,
|
||||
$type->getName()
|
||||
));
|
||||
}
|
||||
|
||||
return $type;
|
||||
|
125
vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Templating/TemplatingRendererEngine.php
vendored
Normal file
125
vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Templating/TemplatingRendererEngine.php
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form\Extension\Templating;
|
||||
|
||||
use Symfony\Component\Form\AbstractRendererEngine;
|
||||
use Symfony\Component\Form\FormViewInterface;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
{
|
||||
/**
|
||||
* @var EngineInterface
|
||||
*/
|
||||
private $engine;
|
||||
|
||||
public function __construct(EngineInterface $engine, array $defaultThemes = array())
|
||||
{
|
||||
parent::__construct($defaultThemes);
|
||||
|
||||
$this->engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderBlock(FormViewInterface $view, $resource, $block, array $variables = array())
|
||||
{
|
||||
return trim($this->engine->render($resource, $variables));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the cache with the resource for a given block name.
|
||||
*
|
||||
* This implementation tries to load as few blocks as possible, since each block
|
||||
* is represented by a template on the file system.
|
||||
*
|
||||
* @see getResourceForBlock()
|
||||
*
|
||||
* @param string $cacheKey The cache key of the form view.
|
||||
* @param FormViewInterface $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
protected function loadResourceForBlock($cacheKey, FormViewInterface $view, $block)
|
||||
{
|
||||
// Recursively try to find the block in the themes assigned to $view,
|
||||
// then of its parent form, then of the parent form of the parent and so on.
|
||||
// When the root form is reached in this recursion, also the default
|
||||
// themes are taken into account.
|
||||
|
||||
// Check each theme whether it contains the searched block
|
||||
if (isset($this->themes[$cacheKey])) {
|
||||
for ($i = count($this->themes[$cacheKey]) - 1; $i >= 0; --$i) {
|
||||
if ($this->loadResourceFromTheme($cacheKey, $block, $this->themes[$cacheKey][$i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the default themes once we reach the root form without success
|
||||
if (!$view->hasParent()) {
|
||||
for ($i = count($this->defaultThemes) - 1; $i >= 0; --$i) {
|
||||
if ($this->loadResourceFromTheme($cacheKey, $block, $this->defaultThemes[$i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we did not find anything in the themes of the current view, proceed
|
||||
// with the themes of the parent view
|
||||
if ($view->hasParent()) {
|
||||
$parentCacheKey = $view->getParent()->getVar(self::CACHE_KEY_VAR);
|
||||
|
||||
if (!isset($this->resources[$parentCacheKey][$block])) {
|
||||
$this->loadResourceForBlock($parentCacheKey, $view->getParent(), $block);
|
||||
}
|
||||
|
||||
// If a template exists in the parent themes, cache that template
|
||||
// for the current theme as well to speed up further accesses
|
||||
if ($this->resources[$parentCacheKey][$block]) {
|
||||
$this->resources[$cacheKey][$block] = $this->resources[$parentCacheKey][$block];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache that we didn't find anything to speed up further accesses
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the resource for a block from a theme.
|
||||
*
|
||||
* @param string $cacheKey The cache key for storing the resource.
|
||||
* @param string $block The name of the block to load a resource for.
|
||||
* @param mixed $theme The theme to load the block from.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
protected function loadResourceFromTheme($cacheKey, $block, $theme)
|
||||
{
|
||||
if ($this->engine->exists($templateName = $theme . ':' . $block . '.html.php')) {
|
||||
$this->resources[$cacheKey][$block] = $templateName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ class FormTypeValidatorExtension extends AbstractTypeExtension
|
||||
};
|
||||
|
||||
// Make sure that validation groups end up as null, closure or array
|
||||
$validationGroupsFilter = function (Options $options, $groups) {
|
||||
$validationGroupsNormalizer = function (Options $options, $groups) {
|
||||
if (empty($groups)) {
|
||||
return null;
|
||||
}
|
||||
@ -72,7 +72,7 @@ class FormTypeValidatorExtension extends AbstractTypeExtension
|
||||
};
|
||||
|
||||
// Constraint should always be converted to an array
|
||||
$constraintsFilter = function (Options $options, $constraints) {
|
||||
$constraintsNormalizer = function (Options $options, $constraints) {
|
||||
return is_object($constraints) ? array($constraints) : (array) $constraints;
|
||||
};
|
||||
|
||||
@ -88,9 +88,9 @@ class FormTypeValidatorExtension extends AbstractTypeExtension
|
||||
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
|
||||
));
|
||||
|
||||
$resolver->setFilters(array(
|
||||
'validation_groups' => $validationGroupsFilter,
|
||||
'constraints' => $constraintsFilter,
|
||||
$resolver->setNormalizers(array(
|
||||
'validation_groups' => $validationGroupsNormalizer,
|
||||
'constraints' => $constraintsNormalizer,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,26 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
*/
|
||||
private $synchronized = true;
|
||||
|
||||
/**
|
||||
* Whether the form's data has been initialized.
|
||||
*
|
||||
* When the data is initialized with its default value, that default value
|
||||
* is passed through the transformer chain in order to synchronize the
|
||||
* model, normalized and view format for the first time. This is done
|
||||
* lazily in order to save performance when {@link setData()} is called
|
||||
* manually, making the initialization with the configured default value
|
||||
* superfluous.
|
||||
*
|
||||
* @var Boolean
|
||||
*/
|
||||
private $initialized = false;
|
||||
|
||||
/**
|
||||
* Whether setData() is currently being called.
|
||||
* @var Boolean
|
||||
*/
|
||||
private $lockSetData = false;
|
||||
|
||||
/**
|
||||
* Creates a new form based on the given configuration.
|
||||
*
|
||||
@ -126,8 +146,8 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
*/
|
||||
public function __construct(FormConfigInterface $config)
|
||||
{
|
||||
if (!$config instanceof UnmodifiableFormConfig) {
|
||||
$config = new UnmodifiableFormConfig($config);
|
||||
if (!$config instanceof ImmutableFormConfig) {
|
||||
$config = new ImmutableFormConfig($config);
|
||||
}
|
||||
|
||||
// Compound forms always need a data mapper, otherwise calls to
|
||||
@ -138,8 +158,6 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
}
|
||||
|
||||
$this->config = $config;
|
||||
|
||||
$this->setData($config->getData());
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
@ -152,7 +170,7 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
/**
|
||||
* Returns the configuration of the form.
|
||||
*
|
||||
* @return UnmodifiableFormConfig The form's immutable configuration.
|
||||
* @return ImmutableFormConfig The form's immutable configuration.
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
@ -327,13 +345,16 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
/**
|
||||
* Updates the form with default data.
|
||||
*
|
||||
* @param array $modelData The data formatted as expected for the underlying object
|
||||
* @param mixed $modelData The data formatted as expected for the underlying object
|
||||
*
|
||||
* @return Form The current form
|
||||
*/
|
||||
public function setData($modelData)
|
||||
{
|
||||
if ($this->bound) {
|
||||
// If the form is bound while disabled, it is set to bound, but the data is not
|
||||
// changed. In such cases (i.e. when the form is not initialized yet) don't
|
||||
// abort this method.
|
||||
if ($this->bound && $this->initialized) {
|
||||
throw new AlreadyBoundException('You cannot change the data of a bound form');
|
||||
}
|
||||
|
||||
@ -346,6 +367,12 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
$modelData = clone $modelData;
|
||||
}
|
||||
|
||||
if ($this->lockSetData) {
|
||||
throw new FormException('A cycle was detected. Listeners to the PRE_SET_DATA event must not call setData(). You should call setData() on the FormEvent object instead.');
|
||||
}
|
||||
|
||||
$this->lockSetData = true;
|
||||
|
||||
// Hook to change content of the data
|
||||
$event = new FormEvent($this, $modelData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::PRE_SET_DATA, $event);
|
||||
@ -395,8 +422,12 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
$this->normData = $normData;
|
||||
$this->viewData = $viewData;
|
||||
$this->synchronized = true;
|
||||
$this->initialized = true;
|
||||
$this->lockSetData = false;
|
||||
|
||||
if ($this->config->getCompound()) {
|
||||
// It is not necessary to invoke this method if the form doesn't have children,
|
||||
// even if the form is compound.
|
||||
if (count($this->children) > 0) {
|
||||
// Update child forms from the data
|
||||
$this->config->getDataMapper()->mapDataToForms($viewData, $this->children);
|
||||
}
|
||||
@ -414,9 +445,29 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
if (!$this->initialized) {
|
||||
$this->setData($this->config->getData());
|
||||
}
|
||||
|
||||
return $this->modelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized data of the form.
|
||||
*
|
||||
* @return mixed When the form is not bound, the default data is returned.
|
||||
* When the form is bound, the normalized bound data is
|
||||
* returned if the form is valid, null otherwise.
|
||||
*/
|
||||
public function getNormData()
|
||||
{
|
||||
if (!$this->initialized) {
|
||||
$this->setData($this->config->getData());
|
||||
}
|
||||
|
||||
return $this->normData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data transformed by the value transformer.
|
||||
*
|
||||
@ -424,6 +475,10 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
*/
|
||||
public function getViewData()
|
||||
{
|
||||
if (!$this->initialized) {
|
||||
$this->setData($this->config->getData());
|
||||
}
|
||||
|
||||
return $this->viewData;
|
||||
}
|
||||
|
||||
@ -543,7 +598,9 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
}
|
||||
|
||||
// Merge form data from children into existing view data
|
||||
if ($this->config->getCompound()) {
|
||||
// It is not necessary to invoke this method if the form has no children,
|
||||
// even if it is compound.
|
||||
if (count($this->children) > 0) {
|
||||
$this->config->getDataMapper()->mapFormsToData($this->children, $viewData);
|
||||
}
|
||||
|
||||
@ -562,7 +619,7 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
// Synchronize representations - must not change the content!
|
||||
$modelData = $this->normToModel($normData);
|
||||
$viewData = $this->normToView($normData);
|
||||
|
||||
|
||||
$synchronized = true;
|
||||
} catch (TransformationFailedException $e) {
|
||||
}
|
||||
@ -573,6 +630,7 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
$this->viewData = $viewData;
|
||||
$this->extraData = $extraData;
|
||||
$this->synchronized = $synchronized;
|
||||
$this->initialized = true;
|
||||
|
||||
$event = new FormEvent($this, $viewData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::POST_BIND, $event);
|
||||
@ -604,18 +662,6 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
return $this->bind($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized data of the form.
|
||||
*
|
||||
* @return mixed When the form is not bound, the default data is returned.
|
||||
* When the form is bound, the normalized bound data is
|
||||
* returned if the form is valid, null otherwise.
|
||||
*/
|
||||
public function getNormData()
|
||||
{
|
||||
return $this->normData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to this form.
|
||||
*
|
||||
@ -833,11 +879,32 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
throw new FormException('You cannot add children to a simple form. Maybe you should set the option "compound" to true?');
|
||||
}
|
||||
|
||||
// Obtain the view data
|
||||
$viewData = null;
|
||||
|
||||
// If setData() is currently being called, there is no need to call
|
||||
// mapDataToForms() here, as mapDataToForms() is called at the end
|
||||
// of setData() anyway. Not doing this check leads to an endless
|
||||
// recursion when initializing the form lazily and an event listener
|
||||
// (such as ResizeFormListener) adds fields depending on the data:
|
||||
//
|
||||
// * setData() is called, the form is not initialized yet
|
||||
// * add() is called by the listener (setData() is not complete, so
|
||||
// the form is still not initialized)
|
||||
// * getViewData() is called
|
||||
// * setData() is called since the form is not initialized yet
|
||||
// * ... endless recursion ...
|
||||
if (!$this->lockSetData) {
|
||||
$viewData = $this->getViewData();
|
||||
}
|
||||
|
||||
$this->children[$child->getName()] = $child;
|
||||
|
||||
$child->setParent($this);
|
||||
|
||||
$this->config->getDataMapper()->mapDataToForms($this->getViewData(), array($child));
|
||||
if (!$this->lockSetData) {
|
||||
$this->config->getDataMapper()->mapDataToForms($viewData, array($child));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
350
vendor/symfony/symfony/src/Symfony/Component/Form/FormRenderer.php
vendored
Normal file
350
vendor/symfony/symfony/src/Symfony/Component/Form/FormRenderer.php
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||
|
||||
/**
|
||||
* Renders a form into HTML using a rendering engine.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class FormRenderer implements FormRendererInterface
|
||||
{
|
||||
/**
|
||||
* @var FormRendererEngineInterface
|
||||
*/
|
||||
private $engine;
|
||||
|
||||
/**
|
||||
* @var CsrfProviderInterface
|
||||
*/
|
||||
private $csrfProvider;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $blockHierarchyMap = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $hierarchyLevelMap = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $variableMap = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $stack = array();
|
||||
|
||||
public function __construct(FormRendererEngineInterface $engine, CsrfProviderInterface $csrfProvider = null)
|
||||
{
|
||||
$this->engine = $engine;
|
||||
$this->csrfProvider = $csrfProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEngine()
|
||||
{
|
||||
return $this->engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTheme(FormViewInterface $view, $themes)
|
||||
{
|
||||
$this->engine->setTheme($view, $themes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderEnctype(FormViewInterface $view)
|
||||
{
|
||||
return $this->renderSection($view, 'enctype');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderRow(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'row', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderRest(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'rest', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderWidget(FormViewInterface $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'widget', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderErrors(FormViewInterface $view)
|
||||
{
|
||||
return $this->renderSection($view, 'errors');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderLabel(FormViewInterface $view, $label = null, array $variables = array())
|
||||
{
|
||||
if ($label !== null) {
|
||||
$variables += array('label' => $label);
|
||||
}
|
||||
|
||||
return $this->renderSection($view, 'label', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderCsrfToken($intention)
|
||||
{
|
||||
if (null === $this->csrfProvider) {
|
||||
throw new \BadMethodCallException('CSRF token can only be generated if a CsrfProviderInterface is injected in the constructor.');
|
||||
}
|
||||
|
||||
return $this->csrfProvider->generateCsrfToken($intention);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderBlock($block, array $variables = array())
|
||||
{
|
||||
if (0 == count($this->stack)) {
|
||||
throw new FormException('This method should only be called while rendering a form element.');
|
||||
}
|
||||
|
||||
list($view, $scopeVariables) = end($this->stack);
|
||||
|
||||
$resource = $this->engine->getResourceForBlock($view, $block);
|
||||
|
||||
if (!$resource) {
|
||||
throw new FormException(sprintf('No block "%s" found while rendering the form.', $block));
|
||||
}
|
||||
|
||||
// Merge the passed with the existing attributes
|
||||
if (isset($variables['attr']) && isset($scopeVariables['attr'])) {
|
||||
$variables['attr'] = array_replace($scopeVariables['attr'], $variables['attr']);
|
||||
}
|
||||
|
||||
// Merge the passed with the exist *label* attributes
|
||||
if (isset($variables['label_attr']) && isset($scopeVariables['label_attr'])) {
|
||||
$variables['label_attr'] = array_replace($scopeVariables['label_attr'], $variables['label_attr']);
|
||||
}
|
||||
|
||||
// Do not use array_replace_recursive(), otherwise array variables
|
||||
// cannot be overwritten
|
||||
$variables = array_replace($scopeVariables, $variables);
|
||||
|
||||
return $this->engine->renderBlock($view, $resource, $block, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isChoiceGroup($choice)
|
||||
{
|
||||
return is_array($choice) || $choice instanceof \Traversable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isChoiceSelected(FormViewInterface $view, ChoiceView $choice)
|
||||
{
|
||||
$value = $view->getVar('value');
|
||||
$choiceValue = $choice->getValue();
|
||||
|
||||
if (is_array($value)) {
|
||||
return false !== array_search($choiceValue, $value, true);
|
||||
}
|
||||
|
||||
return $choiceValue === $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function humanize($text)
|
||||
{
|
||||
return ucfirst(trim(strtolower(preg_replace('/[_\s]+/', ' ', $text))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given section of a form view.
|
||||
*
|
||||
* @param FormViewInterface $view The form view.
|
||||
* @param string $section The name of the section to render.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup.
|
||||
*
|
||||
* @throws Exception\FormException If no fitting template was found.
|
||||
*/
|
||||
protected function renderSection(FormViewInterface $view, $section, array $variables = array())
|
||||
{
|
||||
$renderOnlyOnce = in_array($section, array('row', 'widget'));
|
||||
|
||||
if ($renderOnlyOnce && $view->isRendered()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// The cache key for storing the variables and types
|
||||
$mapKey = $uniqueBlockName = $view->getVar('full_block_name') . '_' . $section;
|
||||
|
||||
// In templates, we have to deal with two kinds of block hierarchies:
|
||||
//
|
||||
// +---------+ +---------+
|
||||
// | Theme B | -------> | Theme A |
|
||||
// +---------+ +---------+
|
||||
//
|
||||
// form_widget -------> form_widget
|
||||
// ^
|
||||
// |
|
||||
// choice_widget -----> choice_widget
|
||||
//
|
||||
// The first kind of hierarchy is the theme hierarchy. This allows to
|
||||
// override the block "choice_widget" from Theme A in the extending
|
||||
// Theme B. This kind of inheritance needs to be supported by the
|
||||
// template engine and, for example, offers "parent()" or similar
|
||||
// functions to fall back from the custom to the parent implementation.
|
||||
//
|
||||
// The second kind of hierarchy is the form type hierarchy. This allows
|
||||
// to implement a custom "choice_widget" block (no matter in which theme),
|
||||
// or to fallback to the block of the parent type, which would be
|
||||
// "form_widget" in this example (again, no matter in which theme).
|
||||
// If the designer wants to explicitly fallback to "form_widget" in his
|
||||
// custom "choice_widget", for example because he only wants to wrap
|
||||
// a <div> around the original implementation, he can simply call the
|
||||
// widget() function again to render the block for the parent type.
|
||||
//
|
||||
// The second kind is implemented in the following blocks.
|
||||
if (!isset($this->blockHierarchyMap[$mapKey])) {
|
||||
// INITIAL CALL
|
||||
// Calculate the hierarchy of template blocks and start on
|
||||
// the bottom level of the hierarchy (= "_<id>_<section>" block)
|
||||
$blockHierarchy = array();
|
||||
foreach ($view->getVar('types') as $type) {
|
||||
$blockHierarchy[] = $type . '_' . $section;
|
||||
}
|
||||
$blockHierarchy[] = $uniqueBlockName;
|
||||
$hierarchyLevel = count($blockHierarchy) - 1;
|
||||
|
||||
// The default variable scope contains all view variables, merged with
|
||||
// the variables passed explicitly to the helper
|
||||
$scopeVariables = $view->getVars();
|
||||
} else {
|
||||
// RECURSIVE CALL
|
||||
// If a block recursively calls renderSection() again, resume rendering
|
||||
// using the parent type in the hierarchy.
|
||||
$blockHierarchy = $this->blockHierarchyMap[$mapKey];
|
||||
$hierarchyLevel = $this->hierarchyLevelMap[$mapKey] - 1;
|
||||
|
||||
// Reuse the current scope and merge it with the explicitly passed variables
|
||||
$scopeVariables = $this->variableMap[$mapKey];
|
||||
}
|
||||
|
||||
// Load the resource where this block can be found
|
||||
$resource = $this->engine->getResourceForBlockHierarchy($view, $blockHierarchy, $hierarchyLevel);
|
||||
|
||||
// Update the current hierarchy level to the one at which the resource was
|
||||
// found. For example, if looking for "choice_widget", but only a resource
|
||||
// is found for its parent "form_widget", then the level is updated here
|
||||
// to the parent level.
|
||||
$hierarchyLevel = $this->engine->getResourceHierarchyLevel($view, $blockHierarchy, $hierarchyLevel);
|
||||
|
||||
// The actually existing block name in $resource
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
|
||||
// Escape if no resource exists for this block
|
||||
if (!$resource) {
|
||||
throw new FormException(sprintf(
|
||||
'Unable to render the form as none of the following blocks exist: "%s".',
|
||||
implode('", "', array_reverse($blockHierarchy))
|
||||
));
|
||||
}
|
||||
|
||||
// Merge the passed with the existing attributes
|
||||
if (isset($variables['attr']) && isset($scopeVariables['attr'])) {
|
||||
$variables['attr'] = array_replace($scopeVariables['attr'], $variables['attr']);
|
||||
}
|
||||
|
||||
// Merge the passed with the exist *label* attributes
|
||||
if (isset($variables['label_attr']) && isset($scopeVariables['label_attr'])) {
|
||||
$variables['label_attr'] = array_replace($scopeVariables['label_attr'], $variables['label_attr']);
|
||||
}
|
||||
|
||||
// Do not use array_replace_recursive(), otherwise array variables
|
||||
// cannot be overwritten
|
||||
$variables = array_replace($scopeVariables, $variables);
|
||||
|
||||
// In order to make recursive calls possible, we need to store the block hierarchy,
|
||||
// the current level of the hierarchy and the variables so that this method can
|
||||
// resume rendering one level higher of the hierarchy when it is called recursively.
|
||||
//
|
||||
// We need to store these values in maps (associative arrays) because within a
|
||||
// call to widget() another call to widget() can be made, but for a different view
|
||||
// object. These nested calls should not override each other.
|
||||
$this->blockHierarchyMap[$mapKey] = $blockHierarchy;
|
||||
$this->hierarchyLevelMap[$mapKey] = $hierarchyLevel;
|
||||
$this->variableMap[$mapKey] = $variables;
|
||||
|
||||
// We also need to store the view and the variables so that we can render custom
|
||||
// blocks with renderBlock() using the same themes and variables as in the outer
|
||||
// block.
|
||||
//
|
||||
// A stack is sufficient for this purpose, because renderBlock() always accesses
|
||||
// the immediate next outer scope, which is always stored at the end of the stack.
|
||||
$this->stack[] = array($view, $variables);
|
||||
|
||||
// Do the rendering
|
||||
$html = $this->engine->renderBlock($view, $resource, $block, $variables);
|
||||
|
||||
// Clear the stack
|
||||
array_pop($this->stack);
|
||||
|
||||
// Clear the maps
|
||||
unset($this->blockHierarchyMap[$mapKey]);
|
||||
unset($this->hierarchyLevelMap[$mapKey]);
|
||||
unset($this->variableMap[$mapKey]);
|
||||
|
||||
if ($renderOnlyOnce) {
|
||||
$view->setRendered();
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
146
vendor/symfony/symfony/src/Symfony/Component/Form/FormRendererEngineInterface.php
vendored
Normal file
146
vendor/symfony/symfony/src/Symfony/Component/Form/FormRendererEngineInterface.php
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/**
|
||||
* Adapter for rendering form templates with a specific templating engine.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface FormRendererEngineInterface
|
||||
{
|
||||
/**
|
||||
* Sets the theme(s) to be used for rendering a view and its children.
|
||||
*
|
||||
* @param FormViewInterface $view The view to assign the theme(s) to.
|
||||
* @param mixed $themes The theme(s). The type of these themes
|
||||
* is open to the implementation.
|
||||
*/
|
||||
public function setTheme(FormViewInterface $view, $themes);
|
||||
|
||||
/**
|
||||
* Returns the resource for a block name.
|
||||
*
|
||||
* The resource is first searched in the themes attached to $view, then
|
||||
* in the themes of its parent view and so on, until a resource was found.
|
||||
*
|
||||
* The type of the resource is decided by the implementation. The resource
|
||||
* is later passed to {@link renderBlock()} by the rendering algorithm.
|
||||
*
|
||||
* @param FormViewInterface $view The view for determining the used themes.
|
||||
* First the themes attached directly to the
|
||||
* view with {@link setTheme()} are considered,
|
||||
* then the ones of its parent etc.
|
||||
* @param string $block The name of the block to render.
|
||||
*
|
||||
* @return mixed The renderer resource or false, if none was found.
|
||||
*/
|
||||
public function getResourceForBlock(FormViewInterface $view, $block);
|
||||
|
||||
/**
|
||||
* Returns the resource for a block hierarchy.
|
||||
*
|
||||
* A block hierarchy is an array which starts with the root of the hierarchy
|
||||
* and continues with the child of that root, the child of that child etc.
|
||||
* The following is an example for a block hierarchy:
|
||||
*
|
||||
* <code>
|
||||
* form_widget
|
||||
* text_widget
|
||||
* url_widget
|
||||
* </code>
|
||||
*
|
||||
* In this example, "url_widget" is the most specific block, while the other
|
||||
* blocks are its ancestors in the hierarchy.
|
||||
*
|
||||
* The second parameter $hierarchyLevel determines the level of the hierarchy
|
||||
* that should be rendered. For example, if $hierarchyLevel is 2 for the
|
||||
* above hierarchy, the engine will first look for the block "url_widget",
|
||||
* then, if that does not exist, for the block "text_widget" etc.
|
||||
*
|
||||
* The type of the resource is decided by the implementation. The resource
|
||||
* is later passed to {@link renderBlock()} by the rendering algorithm.
|
||||
*
|
||||
* @param FormViewInterface $view The view for determining the used
|
||||
* themes. First the themes attached
|
||||
* directly to the view with
|
||||
* {@link setTheme()} are considered,
|
||||
* then the ones of its parent etc.
|
||||
* @param array $blockHierarchy The block name hierarchy, with
|
||||
* the root block at the beginning.
|
||||
* @param integer $hierarchyLevel The level in the hierarchy at
|
||||
* which to start looking. Level 0
|
||||
* indicates the root block, i.e.
|
||||
* the first element of $blockHierarchy.
|
||||
*
|
||||
* @return mixed The renderer resource or false, if none was found.
|
||||
*/
|
||||
public function getResourceForBlockHierarchy(FormViewInterface $view, array $blockHierarchy, $hierarchyLevel);
|
||||
|
||||
/**
|
||||
* Returns the hierarchy level at which a resource can be found.
|
||||
*
|
||||
* A block hierarchy is an array which starts with the root of the hierarchy
|
||||
* and continues with the child of that root, the child of that child etc.
|
||||
* The following is an example for a block hierarchy:
|
||||
*
|
||||
* <code>
|
||||
* form_widget
|
||||
* text_widget
|
||||
* url_widget
|
||||
* </code>
|
||||
*
|
||||
* The second parameter $hierarchyLevel determines the level of the hierarchy
|
||||
* that should be rendered.
|
||||
*
|
||||
* If we call this method with the hierarchy level 2, the engine will first
|
||||
* look for a resource for block "url_widget". If such a resource exists,
|
||||
* the method returns 2. Otherwise it tries to find a resource for block
|
||||
* "text_widget" (at level 1) and, again, returns 1 if a resource was found.
|
||||
* The method continues to look for resources until the root level was
|
||||
* reached and nothing was found. In this case false is returned.
|
||||
*
|
||||
* The type of the resource is decided by the implementation. The resource
|
||||
* is later passed to {@link renderBlock()} by the rendering algorithm.
|
||||
*
|
||||
* @param FormViewInterface $view The view for determining the used
|
||||
* themes. First the themes attached
|
||||
* directly to the view with
|
||||
* {@link setTheme()} are considered,
|
||||
* then the ones of its parent etc.
|
||||
* @param array $blockHierarchy The block name hierarchy, with
|
||||
* the root block at the beginning.
|
||||
* @param integer $hierarchyLevel The level in the hierarchy at
|
||||
* which to start looking. Level 0
|
||||
* indicates the root block, i.e.
|
||||
* the first element of $blockHierarchy.
|
||||
*
|
||||
* @return integer|Boolean The hierarchy level or false, if no resource was found.
|
||||
*/
|
||||
public function getResourceHierarchyLevel(FormViewInterface $view, array $blockHierarchy, $hierarchyLevel);
|
||||
|
||||
/**
|
||||
* Renders a block in the given renderer resource.
|
||||
*
|
||||
* The resource can be obtained by calling {@link getResourceForBlock()}
|
||||
* or {@link getResourceForBlockHierarchy()}. The type of the resource is
|
||||
* decided by the implementation.
|
||||
*
|
||||
* @param FormViewInterface $view The view to render.
|
||||
* @param mixed $resource The renderer resource.
|
||||
* @param string $block The name of the block to render.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup.
|
||||
*/
|
||||
public function renderBlock(FormViewInterface $view, $resource, $block, array $variables = array());
|
||||
}
|
180
vendor/symfony/symfony/src/Symfony/Component/Form/FormRendererInterface.php
vendored
Normal file
180
vendor/symfony/symfony/src/Symfony/Component/Form/FormRendererInterface.php
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
|
||||
/**
|
||||
* Renders a form into HTML.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface FormRendererInterface
|
||||
{
|
||||
/**
|
||||
* Returns the engine used by this renderer.
|
||||
*
|
||||
* @return FormRendererEngineInterface The renderer engine.
|
||||
*/
|
||||
public function getEngine();
|
||||
|
||||
/**
|
||||
* Sets the theme(s) to be used for rendering a view and its children.
|
||||
*
|
||||
* @param FormViewInterface $view The view to assign the theme(s) to.
|
||||
* @param mixed $themes The theme(s). The type of these themes
|
||||
* is open to the implementation.
|
||||
*/
|
||||
public function setTheme(FormViewInterface $view, $themes);
|
||||
|
||||
/**
|
||||
* Renders the HTML enctype in the form tag, if necessary.
|
||||
*
|
||||
* Example usage templates:
|
||||
*
|
||||
* <form action="..." method="post" <?php echo $renderer->renderEnctype($form) ?>>
|
||||
*
|
||||
* @param FormViewInterface $view The view for which to render the encoding type
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderEnctype(FormViewInterface $view);
|
||||
|
||||
/**
|
||||
* Renders the entire row for a form field.
|
||||
*
|
||||
* A row typically contains the label, errors and widget of a field.
|
||||
*
|
||||
* @param FormViewInterface $view The view for which to render the row
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderRow(FormViewInterface $view, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders views which have not already been rendered.
|
||||
*
|
||||
* @param FormViewInterface $view The parent view
|
||||
* @param array $variables An array of variables
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderRest(FormViewInterface $view, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders the HTML for a given view.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* <?php echo $renderer->renderWidget($form) ?>
|
||||
*
|
||||
* You can pass options during the call:
|
||||
*
|
||||
* <?php echo $renderer->renderWidget($form, array('attr' => array('class' => 'foo'))) ?>
|
||||
*
|
||||
* <?php echo $renderer->renderWidget($form, array('separator' => '+++++)) ?>
|
||||
*
|
||||
* @param FormViewInterface $view The view for which to render the widget
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderWidget(FormViewInterface $view, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders the errors of the given view.
|
||||
*
|
||||
* @param FormViewInterface $view The view to render the errors for
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderErrors(FormViewInterface $view);
|
||||
|
||||
/**
|
||||
* Renders the label of the given view.
|
||||
*
|
||||
* @param FormViewInterface $view The view for which to render the label
|
||||
* @param string $label The label
|
||||
* @param array $variables Additional variables passed to the template
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderLabel(FormViewInterface $view, $label = null, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders a named block of the form theme.
|
||||
*
|
||||
* @param string $block The name of the block.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderBlock($block, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders a CSRF token.
|
||||
*
|
||||
* Use this helper for CSRF protection without the overhead of creating a
|
||||
* form.
|
||||
*
|
||||
* <code>
|
||||
* <input type="hidden" name="token" value="<?php $renderer->renderCsrfToken('rm_user_'.$user->getId()) ?>">
|
||||
* </code>
|
||||
*
|
||||
* Check the token in your action using the same intention.
|
||||
*
|
||||
* <code>
|
||||
* $csrfProvider = $this->get('form.csrf_provider');
|
||||
* if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) {
|
||||
* throw new \RuntimeException('CSRF attack detected.');
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $intention The intention of the protected action
|
||||
*
|
||||
* @return string A CSRF token
|
||||
*/
|
||||
public function renderCsrfToken($intention);
|
||||
|
||||
/**
|
||||
* Returns whether the given choice is a group.
|
||||
*
|
||||
* @param mixed $choice A choice
|
||||
*
|
||||
* @return Boolean Whether the choice is a group
|
||||
*/
|
||||
public function isChoiceGroup($choice);
|
||||
|
||||
/**
|
||||
* Returns whether the given choice is selected.
|
||||
*
|
||||
* @param FormViewInterface $view The view of the choice field
|
||||
* @param ChoiceView $choice The choice to check
|
||||
*
|
||||
* @return Boolean Whether the choice is selected
|
||||
*/
|
||||
public function isChoiceSelected(FormViewInterface $view, ChoiceView $choice);
|
||||
|
||||
/**
|
||||
* Makes a technical name human readable.
|
||||
*
|
||||
* Sequences of underscores are replaced by single spaces. The first letter
|
||||
* of the resulting string is capitalized, while all other letters are
|
||||
* turned to lowercase.
|
||||
*
|
||||
* @param string $text The text to humanize.
|
||||
*
|
||||
* @return string The humanized text.
|
||||
*/
|
||||
public function humanize($text);
|
||||
}
|
@ -12,14 +12,14 @@
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\Util\PropertyPath;
|
||||
use Symfony\Component\EventDispatcher\UnmodifiableEventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
|
||||
|
||||
/**
|
||||
* A read-only form configuration.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class UnmodifiableFormConfig implements FormConfigInterface
|
||||
class ImmutableFormConfig implements FormConfigInterface
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
|
||||
@ -134,8 +134,8 @@ class UnmodifiableFormConfig implements FormConfigInterface
|
||||
public function __construct(FormConfigInterface $config)
|
||||
{
|
||||
$dispatcher = $config->getEventDispatcher();
|
||||
if (!$dispatcher instanceof UnmodifiableEventDispatcher) {
|
||||
$dispatcher = new UnmodifiableEventDispatcher($dispatcher);
|
||||
if (!$dispatcher instanceof ImmutableEventDispatcher) {
|
||||
$dispatcher = new ImmutableEventDispatcher($dispatcher);
|
||||
}
|
||||
|
||||
$this->dispatcher = $dispatcher;
|
@ -545,7 +545,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
|
||||
]
|
||||
/following-sibling::div
|
||||
[
|
||||
./label
|
||||
./label[.="child"]
|
||||
/following-sibling::div
|
||||
[
|
||||
./div
|
||||
|
@ -20,7 +20,7 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer;
|
||||
|
||||
class FormTest extends AbstractFormTest
|
||||
class CompoundFormTest extends AbstractFormTest
|
||||
{
|
||||
public function testValidIfAllChildrenAreValid()
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user