typo3 custom widget viewhelper - typo3

I created a custom widget viewhelper for an extension which works fine in an empty typo3 8.7 installation. But when I use it on needed project with same code it causes an error:
#1289422564: initiateSubRequest() can not be called if there is no valid controller extending TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController Got "NULL" in class ...
Did somebody have an error like this before or does someone know what causes this type of error?
<!-- This is the View List.html-->
{namespace Exhibitors = MyVendorName\MyExhibitors\ViewHelpers}
<ul class="second_lvl">
<Exhibitors:widget.AtoZNav objects="{feUserData}" as="filteredExhibitors" property="company">
<Exhibitors:widget.sort objects="{filteredExhibitors}" as="sortedExhibitors" property="company">
<f:for each="{filteredExhibitors}" as="feUser">
<li class="navLink">
{feUser.company}<br />
{feUser.company}
{feUser.www}<br />
</li>
</f:for>
</Exhibitors:widget.sort>
</Exhibitors:widget.AtoZNav>
</ul>
<f:link.action action="show">show detail page</f:link.action>
<?php
/**
* This is the SortViewHelper
*/
namespace MyVendorName\MyExhibitors\ViewHelpers\Widget;
class SortViewHelper extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetViewHelper
{
/**
* #param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $objects
* #param string $as
* #param string $property
* #return string
*/
public function render(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface $objects, $as, $property)
{
return $this->initiateSubRequest();
}
}
<?php
/**
* This is the Sort Controller
*/
namespace MyVendorName\MyExhibitors\ViewHelpers\Widget\Controller;
class SortController extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController
{
/**
* #var \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
protected $objects;
public function initializeAction()
{
$this->objects = $this->widgetConfiguration['objects'];
}
/**
* #param mixed string $order
*/
public function indexAction($order = \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING)
{
$order = ($order == \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING) ? \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING : \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING;
$query = $this->objects->getQuery();
$query->setOrderings(array($this->widgetConfiguration['property'] => $order));
$modifiedObjects = $query->execute();
$this->view->assign('contentArguments', array($this->widgetConfiguration['as'] => $modifiedObjects));
$this->view->assign('order', $order);
}
}
<?php
/**
* This is AtoZNav ViewHelper
*/
namespace MyVendorName\MyExhibitors\ViewHelpers\Widget;
class AtoZNavViewHelper extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetViewHelper
{
/**
* #param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $objects
* #param string $as
* #param string $property
* #return string
*/
public function render(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface $objects, $as, $property)
{
return $this->initiateSubRequest();
}
}
<?php
/**
* This is the Controller
*/
namespace MyVendorName\MyExhibitors\ViewHelpers\Widget\Controller;
class AtoZNavController extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController
{
/**
* #var \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
protected $objects;
public function initializeAction()
{
$this->objects = $this->widgetConfiguration['objects'];
}
/**
* #param string $char
* #throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
*/
public function indexAction($char = '%')
{
$query = $this->objects->getQuery();
$query->matching($query->like($this->widgetConfiguration['property'], $char . '%'));
$modifiedObjects = $query->execute();
$this->view->assign('contentArguments', array($this->widgetConfiguration['as'] => $modifiedObjects));
$this->view->assign('letters', range('A', 'Z'));
$this->view->assign('char', $char);
}
}

I got the same error. You need to inject your controller, like it is done in the fluid pagination widget. This part is missing in the book.
<?php
/**
* This is the SortViewHelper
*/
namespace MyVendorName\MyExhibitors\ViewHelpers\Widget;
class SortViewHelper extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetViewHelper
{
protected $controller;
/**
* #param Controller/SortController $controller
*/
public function injectSortController(Controller\SortController $controller)
{
$this->controller = $controller;
}
/**
* #param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $objects
* #param string $as
* #param string $property
* #return string
*/
public function render(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface $objects, $as, $property)
{
return $this->initiateSubRequest();
}
}

Related

Display an image in a form type of some model SYLIUS

i have created a new model which have an attribute "image" , i have generated the CRUD using the SyliusResourcesBundle ,
what i'm trying to achieve is to display an image in the edit form type , how can i do that ? thx in advance
my form type :
<?php
namespace AppBundle\Form\Type;
use Sylius\Bundle\ResourceBundle\Form\Type\DefaultResourceType as BaseSliderType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class SliderType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('lib','text'
);$builder->add('title','text'
);
$builder->add('description','text'
);
$builder->add('file',FileType::class
);
}
public function getName()
{
return 'app_slider';
}
}
?>
my model:
<?php
namespace AppBundle\Entity;
use Sylius\Component\Resource\Model\ResourceInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* Slider
*/
class Slider implements ResourceInterface, \Serializable
{
/**
* #var int
*/
private $id;
/**
* #var string
*/
private $lib;
/**
* #var string
*/
private $title;
/**
* #var string
*/
private $description;
private $file;
/**
* #return mixed
*/
public function getFile()
{
return $this->file;
}
/**
* #param mixed $file
*/
public function setFile($file)
{
$this->file = $file;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set lib
*
* #param string $lib
* #return Slider
*/
public function setLib($lib)
{
$this->lib = $lib;
return $this;
}
/**
* Get lib
*
* #return string
*/
public function getLib()
{
return $this->lib;
}
/**
* Set title
*
* #param string $title
* #return Slider
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set description
*
* #param string $description
* #return Slider
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* #var string
*/
private $condition;
/**
* Set condition
*
* #param string $condition
* #return Slider
*/
public function setCondition($condition)
{
$this->condition = $condition;
return $this;
}
/**
* Get condition
*
* #return string
*/
public function getCondition()
{
return $this->condition;
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->lib,
$this->title,
$this->description,
// see section on salt below
// $this->salt,
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->lib,
$this->title,
$this->description,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
}

Symfony 2 Doctrine ODM returning errors on existing fields

I have a simple symfony 2 setup with Doctrine ORM and a db with some underscore seperated field names (for instance "error_page"). Querying this never gives a result (getTitle does give a result, getErrorPage is always empty) and symfony gives me an error:
Method "error_page" for object "My\CmsBundle\Document\Website" does not exist in MyCmsBundle:Default:dashboard.html.twig at line 5
I can't figure out why... My Document looks like this:
<?php
// src/My/CmsBundle/Document/Website.php
namespace My\CmsBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(
* collection="websites"
* )
*/
class Website
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $slug;
/**
* #MongoDB\Field(type="string", name="error_page")
*/
protected $error_page = "";
/**
* #MongoDB\String
*/
protected $title;
/**
* #MongoDB\String(name="seo_title")
*/
protected $seo_title;
/**
* #MongoDB\String
*/
protected $seo_description;
/**
* #MongoDB\Collection
*/
protected $url = array();
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set slug
*
* #param string $slug
* #return self
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string $slug
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set title
*
* #param string $title
* #return self
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string $title
*/
public function getTitle()
{
return $this->title;
}
/**
* Set errorPage
*
* #param string $errorPage
* #return self
*/
public function setErrorPage($errorPage)
{
$this->error_page = $errorPage;
return $this;
}
/**
* Get errorPage
*
* #return string $errorPage
*/
public function getErrorPage()
{
return $this->error_page;
}
/**
* Set url
*
* #param collection $url
* #return self
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* Get url
*
* #return collection $url
*/
public function getUrl()
{
return $this->url;
}
/**
* Set seoTitle
*
* #param string $seoTitle
* #return self
*/
public function setSeoTitle($seoTitle)
{
$this->seo_title = $seoTitle;
return $this;
}
/**
* Get seoTitle
*
* #return string $seoTitle
*/
public function getSeoTitle()
{
return $this->seo_title;
}
/**
* Set seoDescription
*
* #param string $seoDescription
* #return self
*/
public function setSeoDescription($seoDescription)
{
$this->seo_description = $seoDescription;
return $this;
}
/**
* Get seoDescription
*
* #return string $seoDescription
*/
public function getSeoDescription()
{
return $this->seo_description;
}
}
Document creation via this document works fine by the way. The field name is also set to error_page as expected... I'm at a loss here :S
Actually, Doctrine+Symfony2 assume camel case variable naming. Twig using the getter method names should be obvious, how should it access protected/private variables? It needs a name for something public : the getter. You're probably wondering why "get" is ignored; it is a simplification for designers as they normally shouldnt know about what "getters" are and the difference between methods and variables.
so in your twig file ,change :
{{document.error_page}}
to
{{document.errorPage}}
this would helpful.

Edit my entity based on and ID of other Entity

i want to edit my Category entity based on Test ID in the form in Twig and bind it to database,
when i open my edit it displays me the forms i edit them but they don't bind the id test from database , i can't understand why, may be something i wrote wrong :(
my controller :
class DefaultController extends Controller
{
function editAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$test = $em->getRepository('LadelaOdeskTesterBundle:Test')->find($id);
if (!$test) {
throw $this->createNotFoundException('Unable to find Advertiser entity.');
}
return array(
'test' => $test,
);
}
/**
* #Route("/new/{id}/update", name="test.update", requirements={"id" = "\d+"})
* #Method("Post")
* #Template("LadelaOdeskTesterBundle:Default:edit.html.twig")
*/
public function updateAction($id)
{
$test =
$this->getDoctrine()->getRepository('LadelaOdeskTesterBundle:Test')->find($id);
if (!$test) {
throw $this->createNotFoundException('Unable to find Test entity.');
}
$success = 0;
$categoryList = array_map('trim', $this->getRequest()->get('category-new'));
$currentCats = $test->getCategories();
foreach ($currentCats as $current){
$test->removeCategorie($current);
}
$em = $this->getDoctrine()->getEntityManager();
foreach ($categoryList as $category) {
if (!empty($category)) {
$categoryName = new Category();
$categoryName->setName($category);
$categoryName->setTest($test);
$test->addCategorie($categoryName);
$em->persist($categoryName);
$success = ' Category ' . $category . ' was created';
}
}
$em->flush();
return $this->redirect($this->generateUrl('test.edit',array('id' => $id)));
return array(
'test' => $test,
);
}
}
my twig file :
{% extends '::base.html.twig' %}
{% block body %}
{#<div class="wrap">#}
<ul id="breadcrumb">
<li><a href="{{path('homepage')}}" title="Home"><img src="{{ \
asset('bundles/ladelaodesktester/images/home.png') }}" alt="Home" class="home"
/></a> </li>
<li> Please add data to new test </li>
</ul>
<h2>Edit Test </h2>
{% for test in tests %}
<form action="{{ path('test.update',{'id': test.id }) }}" method="post">
Category 1<input type="text" name="category-new[]" >
<div id="customWidget">
<div id="colorSelector1"><div style="background-color: #00ff00"></div>
</div>
<div id="colorpickerHolder1"></div>
</div>
Category 2<input type="text" name="category-new[]" ><br>
Category 3<input type="text" name="category-new[]" ><br>
Category 4<input type="text" name="category-new[]" ><br>
Category 5<input type="text" name="category-new[]" ><br>
Category 6<input type="text" name="category-new[]" ><br>
Category 7<input type="text" name="category-new[]" ><br>
Category 8<input type="text" name="category-new[]" ><br>
Category 9<input type="text" name="category-new[]" ><br>
<input type="submit" value="Add">
</form>
{% endfor %}
</div>
Back to Test
{#</div>#}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('bundles/ladelaodesktester/js/new.js') }}"
type="text/javascript"></script>
<script src="{{ asset('bundles/ladelaodesktester/js/colorpicker.js') }}"
type="text/javascript"></script>
{% endblock %}
Category entity:
class Category
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string $color
*
* #ORM\Column(name="color", type="string", length=255)
*/
private $color;
/**
* #var Category category
*
* #ORM\ManyToOne(targetEntity="Test",inversedBy="categories")
* #ORM\JoinColumn(name="test_id", referencedColumnName="id")
*
*/
protected $test;
public function __construct()
{
$this->color = 'rgb(255,255,0)';
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set color
*
* #param string $color
* #return Category
*/
public function setColor($color)
{
$this->color = $color;
return $this;
}
/**
* Get color
*
* #return string
*/
public function getColor()
{
return $this->color;
}
/**
* Set test
*
* #param Ladela\OdeskTesterBundle\Entity\Test $test
* #return Category
*/
public function setTest(\Ladela\OdeskTesterBundle\Entity\Test $test )
{
$this->test = $test;
return $this;
}
/**
* Get test
*
* #return Ladela\OdeskTesterBundle\Entity\Test
*/
public function getTest()
{
return $this->test;
}
}
Test entity:
class Test
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var \DateTime $created_at
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #Gedmo\Slug(fields={"name"})
* #ORM\Column(length=128,unique=true)
*/
private $slug;
/**
* #ORM\ManyToMany(targetEntity="Question")
* #ORM\JoinTable(name="test_questions",
* joinColumns={#ORM\JoinColumn(name="test_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="question_id",
referencedColumnName="id")}
* )
* #var Collection $questions
**/
protected $questions;
/**
* #ORM\ManyToMany(targetEntity="Result")
* #ORM\JoinTable(name="test_results",
* joinColumns={#ORM\JoinColumn(name="test_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="result_id",
referencedColumnName="id")}
* )
* #var Collection $results
**/
protected $results;
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="test")
*/
private $categories;
/**
* #var \DateTime $updated_at
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updated_at", type="datetime")
*/
private $updated_at;
public function __construct()
{
$this->questions = new \Doctrine\Common\Collections\ArrayCollection();
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Test
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getSlug()
{
return $this->slug;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set created_at
*
* #param \DateTime $createdAt
* #return Test
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
return $this;
}
/**
* Get created_at
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set updated_at
*
* #param \DateTime $updatedAt
* #return Test
*/
public function setUpdatedAt($updatedAt)
{
$this->updated_at = $updatedAt;
return $this;
}
/**
* Get updated_at
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updated_at;
}
/**
*
*/
public function getQuestions()
{
return $this->questions;
}
public function addQuestion( Question $question )
{
$this->questions[] = $question;
}
/**
* Set slug
*
* #param string $slug
* #return Test
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Remove questions
*
* #param Question $questions
*/
public function removeQuestion( Question $questions)
{
$this->questions->removeElement($questions);
}
/**
* Add results
*
* #param Result $results
* #return Test
*/
public function addResult(Result $results)
{
$this->results[] = $results;
return $this;
}
/**
* Remove results
*
* #param Result $results
*/
public function removeResult(Result $results)
{
$this->results->removeElement($results);
}
/**
* Get results
*
* #return Collection
*/
public function getResults()
{
return $this->results;
}
public function countResults()
{
return $this->results->count();
}
public function countQuestions()
{
return $this->questions->count();
}
/**
* Add categories
*
* #param Ladela\OdeskTesterBundle\Entity\Category $categories
* #return Test
*/
public function addCategorie(\Ladela\OdeskTesterBundle\Entity\Category $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* #param Ladela\OdeskTesterBundle\Entity\Category $categories
*/
public function removeCategorie(\Ladela\OdeskTesterBundle\Entity\Category $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* #return Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
}
in the foreach loop > if you never add the $test to the category object.
add this:
$categoryName->setTest($test);
the foreach loop should look like this:
$em = $this->getDoctrine()->getManager(); // <---- Changed this
foreach ($categoryList as $category) {
if (!empty($category)) {
$categoryName = new Category();
$categoryName->setName($category);
$categoryName->setTest($test);
$em->persist($categoryName);
$success = ' Category ' . $category . ' was created';
} else {
$success = 'Test category-new may not be empty';
}
}
$em->flush(); // <---- Changed this
Add this before the foreach loop:
$currentCats = $test->getCategories();
foreach ($currentCats as $current){
$test->removeCategorie($current);
}
FINAL EDIT :
Instead of setting test for the category add the category to test, like this:
$em = $this->getDoctrine()->getManager();
foreach ($categoryList as $category) {
if (!empty($category)) {
$categoryName = new Category();
$categoryName->setName($category);
$categoryName->setTest($test);
$test->addCategorie($categoryName); // <---- This is added
$em->persist($categoryName);
$success = ' Category ' . $category . ' was created';
} else {
$success = 'Test category-new may not be empty';
}
}
$em->flush();

Doctrine Mongo document + Embed a Collection of Forms

Project with symfony 2 and mongoDB.
I'm following this tutorial: http://symfony.com/doc/current/cookbook/form/form_collections.html
But once I save the form I get this error:
Cannot create a DBRef, the document is not an object
Line of crash:
https://github.com/doctrine/mongodb-odm/blob/master/lib/Doctrine/ODM/MongoDB/DocumentManager.php#L691
Form code:
namespace Fonts\FontsBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class FamilyType extends AbstractType
{
public function __construct($dm)
{
$this->dm = $dm;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', 'text', array('max_length' => 50, 'error_bubbling' => true));
$builder->add('fonts', 'collection', array(
'type' => new FontType($this->dm),
'allow_add' => true,
'by_reference' => false,
));
}
public function getName()
{
return 'Family';
}
}
Controller code:
namespace Fonts\FontsBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Fonts\FontsBundle\Document\Family;
use Fonts\FontsBundle\Document\Font;
use Fonts\FontsBundle\Form\Type\FamilyType;
class FamilyBackendController extends BaseController
{
public function newAction()
{
try {
$family = new Family();
$form = $this->createForm(new FamilyType($this->getMongoService()), $family);
$request = $this->getRequest();
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid())
{
$this->persist($family);
$this->get('session')->setFlash('notice', 'Item successfully created.');
return ($request->request->get('save') === 'Save') ?
new RedirectResponse($this->generateUrl('backend_familys_list')) :
new RedirectResponse($this->generateUrl('backend_familys_new'));
}
}
return $this->render('FontsBundle:Backend:newFamily.html.twig', array(
'form' => $form->createView(),
));
} catch(\Exception $e) {
return new Response($e->getMessage());
}
}
}
Document:
<?php
namespace Fonts\FontsBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Fonts\FontsBundle\Service\SlugService;
/**
* #MongoDB\Document(repositoryClass="Fonts\FontsBundle\Repository\FamilyRepository")
*/
class Family
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
* #MongoDB\UniqueIndex(safe=true)
* #Assert\NotBlank(message="FamilyName value should not be blank.")
* #Assert\MinLength(limit=3,message="FamilyName must have at least {{ limit }} characters.")
* #Assert\MaxLength(limit=50,message="FamilyName must have maximum {{ limit }} characters.")
*/
protected $name;
/**
* #MongoDB\ReferenceMany(targetDocument="Font", simple=true)
* #Assert\NotBlank(message="Fonts should not be blank.")
*/
protected $fonts;
/**
* #MongoDB\String
* #MongoDB\UniqueIndex(safe=true)
*/
protected $slug;
/**
* #MongoDB\Int
*/
protected $createdAt;
public function __construct()
{
$this->fonts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Family
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string $name
*/
public function getName()
{
return $this->name;
}
/**
* Add fonts
*
* #param Fonts\FontsBundle\Document\Font $fonts
*/
public function addFonts(\Fonts\FontsBundle\Document\Font $fonts)
{
$this->fonts[] = $fonts;
}
/**
* Set fonts
*
* #param Doctrine\Common\Collections\Collection $fonts
*/
public function setFonts($fonts)
{
$this->fonts = $fonts;
}
/**
* Get fonts
*
* #return Doctrine\Common\Collections\Collection $fonts
*/
public function getFonts()
{
return $this->fonts;
}
/**
* Set slug
*
* #param string $slug
* #return Family
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string $slug
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set createdAt
*
* #param int $createdAt
* #return Family
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return int $createdAt
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #MongoDB\PrePersist
*/
public function prePersist()
{
$this->setCreatedAt(time());
$slugService = new SlugService();
$this->setSlug($slugService->slug($this->getName()));
}
/**
* #MongoDB\PreUpdate
*/
public function preUpdate()
{
$slugService = new SlugService();
$this->setSlug($slugService->slug($this->getName()));
}
}
The form crash when I try to persist the object in the controller action_
$this->persist($family);
I tried lot of options but no one with good results. If you have some idea, please reply.

Symfony 2 Embedded forms using one to many db relationship

I'm have a problem embedding forms from different entities in one form, my form is being displayed with firstname [input] lastname [input] address - but the address has no input next to it.
Basically I want to create a form where the user can add first name, last name, address1, address2, city, country ect and submit it it as one, although it's different tables.
The main form is no problem the only issue I'm having is with the second embedded form. Any help would be greatly appreciated.
Here is my code:
Member class:
namespace Pomc\MembersBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pomc\MembersBundle\Entity\Member
*/
class Member
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $firstName
*/
private $firstName;
/**
* #var string $lastName
*/
private $lastName;
/**
* #var Pomc\MembersBundle\Entity\Address
*/
private $address;
/**
* #var Pomc\MembersBundle\Entity\Telephone
*/
private $telephone;
public function __construct()
{
$this->address = new \Doctrine\Common\Collections\ArrayCollection();
$this->telephone = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstName
*
* #param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set lastName
*
* #param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* Get lastName
*
* #return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Add address
*
* #param Pomc\MembersBundle\Entity\Address $address
*/
public function addAddress(\Pomc\MembersBundle\Entity\Address $address)
{
$this->address[] = $address;
}
/**
* Get address
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAddress()
{
return $this->address;
}
/**
* Add telephone
*
* #param Pomc\MembersBundle\Entity\Telephone $telephone
*/
public function addTelephone(\Pomc\MembersBundle\Entity\Telephone $telephone)
{
$this->telephone[] = $telephone;
}
/**
* Get telephone
*
* #return Doctrine\Common\Collections\Collection
*/
public function getTelephone()
{
return $this->telephone;
}
}
Here is the address class:
namespace Pomc\MembersBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pomc\MembersBundle\Entity\Address
*/
class Address
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $addressType
*/
private $addressType;
/**
* #var string $firstLine
*/
private $firstLine;
/**
* #var string $secondLine
*/
private $secondLine;
/**
* #var string $city
*/
private $city;
/**
* #var string $postCode
*/
private $postCode;
/**
* #var string $country
*/
private $country;
/**
* #var Pomc\MembersBundle\Entity\Member
*/
private $member;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set addressType
*
* #param string $addressType
*/
public function setAddressType($addressType)
{
$this->addressType = $addressType;
}
/**
* Get addressType
*
* #return string
*/
public function getAddressType()
{
return $this->addressType;
}
/**
* Set firstLine
*
* #param string $firstLine
*/
public function setFirstLine($firstLine)
{
$this->firstLine = $firstLine;
}
/**
* Get firstLine
*
* #return string
*/
public function getFirstLine()
{
return $this->firstLine;
}
/**
* Set secondLine
*
* #param string $secondLine
*/
public function setSecondLine($secondLine)
{
$this->secondLine = $secondLine;
}
/**
* Get secondLine
*
* #return string
*/
public function getSecondLine()
{
return $this->secondLine;
}
/**
* Set city
*
* #param string $city
*/
public function setCity($city)
{
$this->city = $city;
}
/**
* Get city
*
* #return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set postCode
*
* #param string $postCode
*/
public function setPostCode($postCode)
{
$this->postCode = $postCode;
}
/**
* Get postCode
*
* #return string
*/
public function getPostCode()
{
return $this->postCode;
}
/**
* Set country
*
* #param string $country
*/
public function setCountry($country)
{
$this->country = $country;
}
/**
* Get country
*
* #return string
*/
public function getCountry()
{
return $this->country;
}
/**
* Set member
*
* #param Pomc\MembersBundle\Entity\Member $member
*/
public function setMember(\Pomc\MembersBundle\Entity\Member $member)
{
$this->member = $member;
}
/**
* Get member
*
* #return Pomc\MembersBundle\Entity\Member
*/
public function getMember()
{
return $this->member;
}
}
Here is the memberform:
namespace Pomc\MembersBundle\Form\Type;
use \Symfony\Component\Form\AbstractType;
use \Symfony\Component\Form\FormBuilder;
class MemberType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('firstName');
$builder->add('lastName');
$builder->add('address','collection', array( 'type' => new AddressType(),
'allow_add' => true,
'prototype' => true,
'by_reference' => false,
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Pomc\MembersBundle\Entity\Member');
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
function getName()
{
return 'member';
}
}
Here is the address form:
namespace Pomc\MembersBundle\Form\Type;
use \Symfony\Component\Form\AbstractType;
use \Symfony\Component\Form\FormBuilder;
class AddressType extends AbstractType
{
public function buildForm(Formbuilder $builder, array $options)
{
$builder->add('firstLine');
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Pomc\MembersBundle\Entity\Address');
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
function getName()
{
return 'address';
}
function getIdentifier()
{
return 'address';
}
}
Here is the controller:
namespace Pomc\MembersBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use \Pomc\MembersBundle\Entity\Member;
use \Symfony\Component\HttpFoundation\Request;
use \Pomc\MembersBundle\Form\Type\MemberType;
class DefaultController extends Controller
{
public function indexAction($name)
{
return $this->render('PomcMembersBundle:Default:index.html.twig', array('name' => $name));
}
public function newAction(Request $request)
{
$member = new Member();
$form = $this->get('form.factory')->create(new MemberType());
if($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if($form->isValid())
{
$em = $this->getDoctrine()->getEntityManager();
$em->persist($member);
$em->flush();
}
}
return $this->render('PomcMembersBundle:Default:new.html.twig', array( 'form'=> $form->createView(),));
}
}
Here is the template:
<form action="{{ path('member_new') }}" method="post" {{ form_enctype(form)}}>
{{ form_widget(form) }}
<div>
{{ form_row(form.address)}}
</div>
<input type="submit" />
</form>
Been a long time user of this site, but this is my first question.
Thank you
Oh I faced the same problem, but I found the solution, hope this will help you :-)
You're forgetting to add an Address object to the member entity.
In your action you'll need to do the following:
$member = new Member();
$member->addAddress(new Address());
$form = $this->createForm(new MemberType(), $member);
And then in your template:
{% for address in form.address %}
{{ form_widget(address.firstLine) }}
{% endfor %}
Btw your 'firstline' widget doesn't relate to an entity property.
Btw if you called addAddress two times, you would of course get two 'firstline' widgets in your form.
Hope this works. best of luck.
Llewellyn, do you mean something like thid:
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('imBundle:Inspecciones')->find($id);
$entity_valores = $em->getRepository('imBundle:ValoresInspecciones')->findByInspecciones($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Inspecciones entity.');
}
$entity->setValoresInspecciones($entity_valores);
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('imBundle:Inspecciones:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}