2010-06-24 09:40:05 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
2011-01-15 13:29:43 +00:00
|
|
|
* This file is part of the Symfony package.
|
2010-10-02 11:38:11 +01:00
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
2010-06-24 09:40:05 +01:00
|
|
|
*
|
2011-01-15 13:29:43 +00:00
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
2010-06-24 09:40:05 +01:00
|
|
|
*/
|
|
|
|
|
2011-01-15 13:29:43 +00:00
|
|
|
namespace Symfony\Component\Form;
|
|
|
|
|
2011-01-28 22:09:22 +00:00
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
|
|
use Symfony\Component\HttpFoundation\FileBag;
|
2010-10-02 11:38:11 +01:00
|
|
|
use Symfony\Component\Validator\ValidatorInterface;
|
2011-02-03 09:53:51 +00:00
|
|
|
use Symfony\Component\Validator\ExecutionContext;
|
2011-03-17 14:22:10 +00:00
|
|
|
use Symfony\Component\Form\Event\DataEvent;
|
2011-03-16 17:20:13 +00:00
|
|
|
use Symfony\Component\Form\Event\FilterDataEvent;
|
2010-12-15 14:36:47 +00:00
|
|
|
use Symfony\Component\Form\Exception\FormException;
|
2011-02-02 08:41:57 +00:00
|
|
|
use Symfony\Component\Form\Exception\MissingOptionsException;
|
2011-03-17 13:55:11 +00:00
|
|
|
use Symfony\Component\Form\Exception\AlreadyBoundException;
|
2011-01-29 21:39:36 +00:00
|
|
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
|
|
|
use Symfony\Component\Form\Exception\DanglingFieldException;
|
|
|
|
use Symfony\Component\Form\Exception\FieldDefinitionException;
|
2011-01-25 08:56:37 +00:00
|
|
|
use Symfony\Component\Form\CsrfProvider\CsrfProviderInterface;
|
2011-03-18 11:50:26 +00:00
|
|
|
use Symfony\Component\Form\ValueTransformer\ValueTransformerInterface;
|
|
|
|
use Symfony\Component\Form\DataMapper\DataMapperInterface;
|
|
|
|
use Symfony\Component\Form\Renderer\RendererInterface;
|
2011-03-16 17:20:13 +00:00
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
2010-10-02 11:38:11 +01:00
|
|
|
|
2010-06-24 09:40:05 +01:00
|
|
|
/**
|
|
|
|
* Form represents a form.
|
|
|
|
*
|
|
|
|
* A form is composed of a validator schema and a widget form schema.
|
|
|
|
*
|
2011-01-28 22:09:22 +00:00
|
|
|
* Form also takes care of CSRF protection by default.
|
2010-06-24 09:40:05 +01:00
|
|
|
*
|
2011-01-28 22:09:22 +00:00
|
|
|
* A CSRF secret can be any random string. If set to false, it disables the
|
|
|
|
* CSRF protection, and if set to null, it forces the form to use the global
|
|
|
|
* CSRF secret. If the global CSRF secret is also null, then a random one
|
2010-06-24 09:40:05 +01:00
|
|
|
* is generated on the fly.
|
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
|
|
|
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
2010-06-24 09:40:05 +01:00
|
|
|
*/
|
2011-03-18 11:50:26 +00:00
|
|
|
class Form extends Field implements \IteratorAggregate, FormInterface
|
2010-06-24 09:40:05 +01:00
|
|
|
{
|
2011-01-25 08:56:37 +00:00
|
|
|
/**
|
2011-01-29 21:39:36 +00:00
|
|
|
* Contains all the fields of this group
|
|
|
|
* @var array
|
2011-01-25 08:56:37 +00:00
|
|
|
*/
|
2011-02-21 22:40:12 +00:00
|
|
|
private $fields = array();
|
2011-01-29 21:39:36 +00:00
|
|
|
|
|
|
|
/**
|
2011-03-17 13:55:11 +00:00
|
|
|
* Contains the names of bound values who don't belong to any fields
|
2011-01-29 21:39:36 +00:00
|
|
|
* @var array
|
|
|
|
*/
|
2011-02-21 22:40:12 +00:00
|
|
|
private $extraFields = array();
|
2010-06-24 10:24:08 +01:00
|
|
|
|
2011-02-21 22:40:12 +00:00
|
|
|
private $virtual;
|
2011-01-05 11:36:04 +00:00
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
private $dataMapper;
|
2010-06-24 10:24:08 +01:00
|
|
|
|
2011-03-17 10:03:10 +00:00
|
|
|
public function __construct($name, EventDispatcherInterface $dispatcher,
|
2011-03-18 11:50:26 +00:00
|
|
|
RendererInterface $renderer, ValueTransformerInterface $valueTransformer = null,
|
|
|
|
ValueTransformerInterface $normalizationTransformer = null,
|
|
|
|
DataMapperInterface $dataMapper,
|
|
|
|
$disabled, $modifyByReference, $propertyPath, $required,
|
|
|
|
$validationGroups, $virtual)
|
2011-03-01 13:19:28 +00:00
|
|
|
{
|
2011-03-18 11:50:26 +00:00
|
|
|
$dispatcher->addListener(array(
|
|
|
|
Events::postSetData,
|
|
|
|
Events::preBind,
|
|
|
|
Events::filterSetData,
|
|
|
|
Events::filterBoundDataFromClient,
|
|
|
|
), $this);
|
2011-03-16 17:20:13 +00:00
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
$this->virtual = $virtual;
|
|
|
|
$this->dataMapper = $dataMapper;
|
2011-03-01 13:19:28 +00:00
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
parent::__construct($name, $dispatcher, $renderer, $valueTransformer,
|
|
|
|
$normalizationTransformer, $disabled, $modifyByReference,
|
|
|
|
$propertyPath, $required, $validationGroups);
|
2011-03-01 13:19:28 +00:00
|
|
|
}
|
|
|
|
|
2011-01-29 21:39:36 +00:00
|
|
|
/**
|
2011-03-18 11:50:26 +00:00
|
|
|
* Returns all fields in this group
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
2011-03-18 11:50:26 +00:00
|
|
|
* @return array
|
2011-01-29 21:39:36 +00:00
|
|
|
*/
|
2011-03-18 11:50:26 +00:00
|
|
|
public function getFields()
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-18 11:50:26 +00:00
|
|
|
return $this->fields;
|
|
|
|
}
|
2011-01-29 21:39:36 +00:00
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
public function add(FieldInterface $field)
|
|
|
|
{
|
2011-03-17 10:03:10 +00:00
|
|
|
$this->fields[$field->getName()] = $field;
|
2011-01-29 21:39:36 +00:00
|
|
|
|
|
|
|
$field->setParent($this);
|
|
|
|
|
|
|
|
$data = $this->getTransformedData();
|
|
|
|
|
|
|
|
if (!empty($data)) {
|
2011-03-18 11:50:26 +00:00
|
|
|
$this->dataMapper->mapDataToField($data, $field);
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-17 10:03:10 +00:00
|
|
|
public function remove($name)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-18 11:50:26 +00:00
|
|
|
if (isset($this->fields[$name])) {
|
|
|
|
$this->fields[$name]->setParent(null);
|
2011-01-29 21:39:36 +00:00
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
unset($this->fields[$name]);
|
|
|
|
}
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-03-17 10:03:10 +00:00
|
|
|
* Returns whether a field with the given name exists.
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
2011-03-17 10:03:10 +00:00
|
|
|
* @param string $name
|
2011-01-29 21:39:36 +00:00
|
|
|
* @return Boolean
|
|
|
|
*/
|
2011-03-17 10:03:10 +00:00
|
|
|
public function has($name)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-17 10:03:10 +00:00
|
|
|
return isset($this->fields[$name]);
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-03-17 10:03:10 +00:00
|
|
|
* Returns the field with the given name.
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
2011-03-17 10:03:10 +00:00
|
|
|
* @param string $name
|
2011-01-29 21:39:36 +00:00
|
|
|
* @return FieldInterface
|
|
|
|
*/
|
2011-03-17 10:03:10 +00:00
|
|
|
public function get($name)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-17 10:03:10 +00:00
|
|
|
if (isset($this->fields[$name])) {
|
|
|
|
return $this->fields[$name];
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
2011-03-17 10:03:10 +00:00
|
|
|
throw new \InvalidArgumentException(sprintf('Field "%s" does not exist.', $name));
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
public function postSetData(DataEvent $event)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-18 11:50:26 +00:00
|
|
|
$form = $event->getField();
|
|
|
|
$data = $form->getTransformedData();
|
|
|
|
|
|
|
|
$this->dataMapper->mapDataToForm($data, $form);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function filterSetData(FilterDataEvent $event)
|
|
|
|
{
|
|
|
|
$field = $event->getField();
|
|
|
|
|
|
|
|
if (null === $field->getValueTransformer() && null === $field->getNormalizationTransformer()) {
|
|
|
|
$data = $event->getData();
|
|
|
|
|
|
|
|
if (empty($data)) {
|
|
|
|
$event->setData($this->dataMapper->createEmptyData());
|
|
|
|
}
|
|
|
|
}
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
2011-03-16 17:20:13 +00:00
|
|
|
public function filterBoundDataFromClient(FilterDataEvent $event)
|
2011-03-01 13:19:28 +00:00
|
|
|
{
|
2011-03-16 17:20:13 +00:00
|
|
|
$data = $event->getData();
|
|
|
|
|
2011-03-01 13:19:28 +00:00
|
|
|
if (!is_array($data)) {
|
|
|
|
throw new UnexpectedTypeException($data, 'array');
|
|
|
|
}
|
|
|
|
|
2011-03-17 10:03:10 +00:00
|
|
|
foreach ($this->fields as $name => $field) {
|
|
|
|
if (!isset($data[$name])) {
|
|
|
|
$data[$name] = null;
|
2011-03-01 13:19:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-17 10:03:10 +00:00
|
|
|
foreach ($data as $name => $value) {
|
|
|
|
if ($this->has($name)) {
|
2011-03-17 13:55:11 +00:00
|
|
|
$this->fields[$name]->bind($value);
|
2011-03-01 13:19:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
$data = $this->getTransformedData();
|
2011-03-01 13:19:28 +00:00
|
|
|
|
2011-03-18 11:50:26 +00:00
|
|
|
$this->dataMapper->mapFormToData($this, $data);
|
|
|
|
|
|
|
|
$event->setData($data);
|
2011-02-24 11:22:00 +00:00
|
|
|
}
|
|
|
|
|
2011-03-17 14:22:10 +00:00
|
|
|
public function preBind(DataEvent $event)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
|
|
|
$this->extraFields = array();
|
|
|
|
|
2011-03-17 14:22:10 +00:00
|
|
|
foreach ((array)$event->getData() as $name => $value) {
|
2011-03-17 10:03:10 +00:00
|
|
|
if (!$this->has($name)) {
|
|
|
|
$this->extraFields[] = $name;
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public function isVirtual()
|
|
|
|
{
|
2011-02-21 22:40:12 +00:00
|
|
|
return $this->virtual;
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-03-17 13:55:11 +00:00
|
|
|
* Returns whether this form was bound with extra fields
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
|
|
|
* @return Boolean
|
|
|
|
*/
|
2011-03-17 13:55:11 +00:00
|
|
|
public function isBoundWithExtraFields()
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
|
|
|
// TODO: integrate the field names in the error message
|
|
|
|
return count($this->extraFields) > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether the field is valid.
|
|
|
|
*
|
|
|
|
* @return Boolean
|
|
|
|
*/
|
|
|
|
public function isValid()
|
|
|
|
{
|
|
|
|
if (!parent::isValid()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($this->fields as $field) {
|
|
|
|
if (!$field->isValid()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-02-01 09:59:18 +00:00
|
|
|
* Returns true if the field exists (implements the \ArrayAccess interface).
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
2011-03-17 10:03:10 +00:00
|
|
|
* @param string $name The name of the field
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
|
|
|
* @return Boolean true if the widget exists, false otherwise
|
|
|
|
*/
|
2011-03-17 10:03:10 +00:00
|
|
|
public function offsetExists($name)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-17 10:03:10 +00:00
|
|
|
return $this->has($name);
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the form field associated with the name (implements the \ArrayAccess interface).
|
|
|
|
*
|
2011-03-17 10:03:10 +00:00
|
|
|
* @param string $name The offset of the value to get
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
|
|
|
* @return Field A form field instance
|
|
|
|
*/
|
2011-03-17 10:03:10 +00:00
|
|
|
public function offsetGet($name)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-17 10:03:10 +00:00
|
|
|
return $this->get($name);
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Throws an exception saying that values cannot be set (implements the \ArrayAccess interface).
|
|
|
|
*
|
|
|
|
* @param string $offset (ignored)
|
|
|
|
* @param string $value (ignored)
|
|
|
|
*
|
|
|
|
* @throws \LogicException
|
|
|
|
*/
|
2011-03-17 10:03:10 +00:00
|
|
|
public function offsetSet($name, $field)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-18 11:50:26 +00:00
|
|
|
throw new \BadMethodCallException('offsetSet() is not supported');
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Throws an exception saying that values cannot be unset (implements the \ArrayAccess interface).
|
|
|
|
*
|
2011-03-17 10:03:10 +00:00
|
|
|
* @param string $name
|
2011-01-29 21:39:36 +00:00
|
|
|
*
|
|
|
|
* @throws \LogicException
|
|
|
|
*/
|
2011-03-17 10:03:10 +00:00
|
|
|
public function offsetUnset($name)
|
2011-01-29 21:39:36 +00:00
|
|
|
{
|
2011-03-18 11:50:26 +00:00
|
|
|
throw new \BadMethodCallException('offsetUnset() is not supported');
|
2011-01-29 21:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the iterator for this group.
|
|
|
|
*
|
|
|
|
* @return \ArrayIterator
|
|
|
|
*/
|
|
|
|
public function getIterator()
|
|
|
|
{
|
|
|
|
return new \ArrayIterator($this->fields);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the number of form fields (implements the \Countable interface).
|
|
|
|
*
|
|
|
|
* @return integer The number of embedded form fields
|
|
|
|
*/
|
|
|
|
public function count()
|
|
|
|
{
|
|
|
|
return count($this->fields);
|
|
|
|
}
|
|
|
|
|
2011-02-21 22:40:12 +00:00
|
|
|
/**
|
|
|
|
* Returns whether the CSRF token is valid
|
|
|
|
*
|
|
|
|
* @return Boolean
|
|
|
|
*/
|
|
|
|
public function isCsrfTokenValid()
|
|
|
|
{
|
|
|
|
if (!$this->isCsrfProtected()) {
|
|
|
|
return true;
|
|
|
|
} else {
|
2011-03-17 13:28:59 +00:00
|
|
|
$token = $this->get($this->csrfFieldName)->getTransformedData();
|
2011-02-21 22:40:12 +00:00
|
|
|
|
|
|
|
return $this->csrfProvider->isCsrfTokenValid(get_class($this), $token);
|
|
|
|
}
|
2011-01-05 11:36:04 +00:00
|
|
|
}
|
|
|
|
|
2010-06-24 10:24:08 +01:00
|
|
|
/**
|
2011-02-01 09:59:18 +00:00
|
|
|
* Binds a request to the form
|
2010-06-24 10:24:08 +01:00
|
|
|
*
|
2011-03-17 13:55:11 +00:00
|
|
|
* If the request was a POST request, the data is bound to the form,
|
2011-02-01 09:59:18 +00:00
|
|
|
* transformed and written into the form data (an object or an array).
|
|
|
|
* You can set the form data by passing it in the second parameter
|
|
|
|
* of this method or by passing it in the "data" option of the form's
|
|
|
|
* constructor.
|
|
|
|
*
|
|
|
|
* @param Request $request The request to bind to the form
|
|
|
|
* @param array|object $data The data from which to read default values
|
2011-03-17 13:55:11 +00:00
|
|
|
* and where to write bound values
|
2011-01-28 22:09:22 +00:00
|
|
|
*/
|
2011-03-17 13:51:22 +00:00
|
|
|
public function bindRequest(Request $request)
|
2011-01-28 22:09:22 +00:00
|
|
|
{
|
2011-03-17 13:55:11 +00:00
|
|
|
// Store the bound data in case of a post request
|
2011-03-17 13:51:22 +00:00
|
|
|
switch ($request->getMethod()) {
|
|
|
|
case 'POST':
|
|
|
|
case 'PUT':
|
|
|
|
$data = array_replace_recursive(
|
|
|
|
$request->request->get($this->getName(), array()),
|
|
|
|
$request->files->get($this->getName(), array())
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case 'GET':
|
|
|
|
$data = $request->query->get($this->getName(), array());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new FormException(sprintf('The request method "%s" is not supported', $request->getMethod()));
|
2011-02-01 09:59:18 +00:00
|
|
|
}
|
2011-03-17 13:51:22 +00:00
|
|
|
|
2011-03-17 13:55:11 +00:00
|
|
|
$this->bind($data);
|
2011-01-28 22:09:22 +00:00
|
|
|
}
|
2010-09-09 14:23:28 +01:00
|
|
|
|
2010-06-24 10:24:08 +01:00
|
|
|
/**
|
|
|
|
* Returns whether the maximum POST size was reached in this request.
|
|
|
|
*
|
2011-01-21 01:39:28 +00:00
|
|
|
* @return Boolean
|
2010-06-24 10:24:08 +01:00
|
|
|
*/
|
|
|
|
public function isPostMaxSizeReached()
|
|
|
|
{
|
2011-01-28 22:13:10 +00:00
|
|
|
if ($this->isRoot() && isset($_SERVER['CONTENT_LENGTH'])) {
|
2010-06-24 10:24:08 +01:00
|
|
|
$length = (int) $_SERVER['CONTENT_LENGTH'];
|
|
|
|
$max = trim(ini_get('post_max_size'));
|
|
|
|
|
|
|
|
switch (strtolower(substr($max, -1))) {
|
|
|
|
// The 'G' modifier is available since PHP 5.1.0
|
|
|
|
case 'g':
|
|
|
|
$max *= 1024;
|
|
|
|
case 'm':
|
|
|
|
$max *= 1024;
|
|
|
|
case 'k':
|
|
|
|
$max *= 1024;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $length > $max;
|
|
|
|
}
|
2011-02-27 17:27:46 +00:00
|
|
|
|
|
|
|
return false;
|
2010-06-24 10:24:08 +01:00
|
|
|
}
|
|
|
|
|
2011-02-03 09:53:51 +00:00
|
|
|
/**
|
|
|
|
* Validates the data of this form
|
|
|
|
*
|
|
|
|
* This method is called automatically during the validation process.
|
|
|
|
*
|
|
|
|
* @param ExecutionContext $context The current validation context
|
|
|
|
*/
|
|
|
|
public function validateData(ExecutionContext $context)
|
|
|
|
{
|
2011-02-04 09:12:11 +00:00
|
|
|
if (is_object($this->getData()) || is_array($this->getData())) {
|
|
|
|
$groups = $this->getValidationGroups();
|
|
|
|
$propertyPath = $context->getPropertyPath();
|
|
|
|
$graphWalker = $context->getGraphWalker();
|
2011-02-03 09:53:51 +00:00
|
|
|
|
2011-02-04 09:12:11 +00:00
|
|
|
if (null === $groups) {
|
|
|
|
$groups = array(null);
|
|
|
|
}
|
2011-02-03 09:53:51 +00:00
|
|
|
|
2011-02-04 09:12:11 +00:00
|
|
|
// The Execute constraint is called on class level, so we need to
|
|
|
|
// set the property manually
|
|
|
|
$context->setCurrentProperty('data');
|
2011-02-03 09:53:51 +00:00
|
|
|
|
2011-02-04 09:12:11 +00:00
|
|
|
// Adjust the property path accordingly
|
|
|
|
if (!empty($propertyPath)) {
|
|
|
|
$propertyPath .= '.';
|
|
|
|
}
|
2011-02-03 09:53:51 +00:00
|
|
|
|
2011-02-04 09:12:11 +00:00
|
|
|
$propertyPath .= 'data';
|
2011-02-03 09:53:51 +00:00
|
|
|
|
2011-02-04 09:12:11 +00:00
|
|
|
foreach ($groups as $group) {
|
|
|
|
$graphWalker->walkReference($this->getData(), $group, $propertyPath, true);
|
|
|
|
}
|
2011-02-03 09:53:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-16 09:28:33 +00:00
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function isEmpty()
|
|
|
|
{
|
|
|
|
foreach ($this->fields as $field) {
|
|
|
|
if (!$field->isEmpty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-06-24 09:40:05 +01:00
|
|
|
}
|