Foreign key not stored in database using embed form in symfony 3 - database

I have the following entities, form types and controller
Entity Client
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Client
*
* #ORM\Table(name="client")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ClientRepository")
*/
class Client
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* #ORM\OneToMany(targetEntity="Contacts", mappedBy="client", cascade={"persist"})
*/
private $contacts;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Client
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set address
*
* #param string $address
*
* #return Client
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* #return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Constructor
*/
public function __construct()
{
$this->contacts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add contact
*
* #param \AppBundle\Entity\Contacts $contact
*
* #return Client
*/
public function addContact(\AppBundle\Entity\Contacts $contact)
{
$this->contacts[] = $contact;
return $this;
}
/**
* Remove contact
*
* #param \AppBundle\Entity\Contacts $contact
*/
public function removeContact(\AppBundle\Entity\Contacts $contact)
{
$this->contacts->removeElement($contact);
}
/**
* Get contacts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getContacts()
{
return $this->contacts;
}
}
Contacts entity is as below
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Contacts
*
* #ORM\Table(name="contacts")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ContactsRepository")
*/
class Contacts
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="fullname", type="string", length=255)
*/
private $fullname;
/**
* #var int
*
* #ORM\Column(name="user_type", type="smallint")
*/
private $userType;
/**
* #ORM\ManyToOne(targetEntity="Client", inversedBy="contacts")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
private $client;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set fullname
*
* #param string $fullname
*
* #return Contacts
*/
public function setFullname($fullname)
{
$this->fullname = $fullname;
return $this;
}
/**
* Get fullname
*
* #return string
*/
public function getFullname()
{
return $this->fullname;
}
/**
* Set userType
*
* #param integer $userType
*
* #return Contacts
*/
public function setUserType($userType)
{
$this->userType = $userType;
return $this;
}
/**
* Get userType
*
* #return int
*/
public function getUserType()
{
return $this->userType;
}
/**
* Set client
*
* #param \AppBundle\Entity\Client $client
*
* #return Contacts
*/
public function setClient(\AppBundle\Entity\Client $client = null)
{
$this->client = $client;
return $this;
}
/**
* Get client
*
* #return \AppBundle\Entity\Client
*/
public function getClient()
{
return $this->client;
}
}
Client form type is as below
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use AppBundle\Entity\Client;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class ClientForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, array('attr' => array('class' => 'form-control', 'placeholder' => 'Client Name')))
->add('address', TextType::class, array('attr' => array('class' => 'form-control', 'placeholder' => 'Address')))
->add('contacts', CollectionType::class, array(
// each entry in the array will be an "email" field
'entry_type' => ContactsForm::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
))
->add('save', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Client::class,
));
}
}
Contacts form type is as below
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Contacts;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class ContactsForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('fullname', TextType::class, array('attr' => array('class' => 'form-control', 'placeholder' => 'Full Name')))
->add('user_type', TextType::class, array('attr' => array('class' => 'form-control', 'placeholder' => 'Co-Owner'))
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Contacts::class,
));
}
}
Finally the controller to store data in two different tables being client as main table and contacts having foreign ken as client_id from table client is as below
/
**
* #Route("/client/add", name="add_client")
*/
public function addClientAction(Request $request)
{
$client = new Client();
$form = $this->createForm(ClientForm::class, $client);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$client = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($client);
$em->flush();
$this->addFlash(
'notice',
'Client Added!'
);
return $this->redirectToRoute('homepage');
}
return $this->render('default/addClient.html.twig', array('form' => $form->createView()));
}
The problem here is the data is added in both tables but the foreign key of the added client is not stored in table contacts, the value is null
This solution seems to work for some people may be for older version of symfony
But not luck to me. How to insert the foreign id as well. Am new to symfony and I am using symfony 3.2

It seems for me like a little mess up.
I guess you should add a contact from ContactController addAction.
Than in your Contact form type add EntityType, so you can choose a client for your contact. Here is some examples: http://symfony.com/doc/current/reference/forms/types/entity.html
Or you can set client manually by simple $contact->setClient($client) before you presist.
PS: rename Contacts entity to Contact. It is a little confusing)

Related

Creating sorted array for KnpLabs/KnpMenu

I want to create a sorted Menu in PHP, Symfony which could be very deep.
Therefor I have added 2 fields in category db (parent_id, sort).
My problem is to get a sorted array like:
array(
//MAIN CATEGORY 1
array(
'id' => 1,
'name' => 'Main',
'child'=> false
),
//MAIN CATEGORY 2
array(
'id' => 2,
'name' => 'Main2',
'child'=> false
),
//MAIN CATEGORY 3
array(
'id' => 6,
'name' => 'Main3',
'child'=> array(
array(
'id' => 4,
'name' => 'Sub of Main3',
'child'=> array(
'id' => 4,
'name' => 'Sub Sub og Main3',
'child'=> false
)
),
array(
'id' => 7,
'name' => '2. Sub og Main3',
'child'=> false
)
)
)
);
So I can use it to create the menu with KnpMenu Bundle.
I could not find another way, which is economical in performance and works with this bundle.
Can anybody help me, how to create the array out of the DB?
I tested something around and found a solution with knpMenuBundle like this:
namespace AppBundle\Menu;
use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
class Builder implements ContainerAwareInterface
{
use ContainerAwareTrait;
public function mainMenu(FactoryInterface $factory, array $options)
{
$em = $this->container->get('doctrine')->getManager();
$mandant = $this->container->get('session')->get('mandantId');
$nodes = $em->getRepository('AppBundle:Categories')->findSorted($mandant);
$menu = $factory->createItem('root');
$menu->addChild('Startseite', array('route' => 'homepage'));
foreach($nodes as $node)
{
$childMenu = $menu->addChild($node['name'],array('route' => $node['route']));
$this->loadChild($childMenu,$node);
}
return $menu;
}
private function loadChild($childMenu,array $node)
{
if(isset($node['child']))
{
foreach ($node['child'] as $child)
{
$childMenu = $childMenu->addChild($child['name'],array('route' => $child['route']));
$this->loadChild($childMenu,$child);
}
}
return;
}
I had a very similar issue and here is how I solved it.
So my page entity looks something like this:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Knp\Menu\NodeInterface;
/**
* Page
*
* #ORM\Table(name="PAGE")
* #ORM\Entity()
*/
class Page implements NodeInterface
{
/**
* #var int
*
* #ORM\Column(name="ID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="TITLE", type="string", length=255)
*/
private $title;
/**
* page | link | pdf
* #var string
*
* #ORM\Column(name="CONTENT_TYPE", type="string", length=255)
*/
private $contentType;
/**
* A page can have one parent
*
* #var FacetPage
*
* #ORM\ManyToOne(targetEntity="Page", inversedBy="childrenPages")
* #ORM\JoinColumn(name="PARENT_PAGE_ID", referencedColumnName="ID")
*/
private $parentPage;
/**
* A parent can have multiple children
*
* #var arrayCollection
*
* #ORM\OneToMany(targetEntity="Page", mappedBy="parentPage")
*
*/
private $childrenPages;
/**
* #var resource
*
* #ORM\Column(name="CONTENT", type="text", length=200000)
*/
private $content;
/**
* Many pages could have many allowed roles
*
* #var arrayCollection
*
* #ORM\ManyToMany(targetEntity="Role")
* #ORM\JoinTable(name="PAGE_ALLOWED_ROLES",
* joinColumns={#ORM\JoinColumn(name="page_id", referencedColumnName="ID")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="ID")}
* )
*/
private $allowedRoles;
/**
* #var string
*
* #ORM\Column(name="SLUG", type="string", nullable=true)
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="PERMALINK", type="string", nullable=true)
*/
private $permalink;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="CREATED_BY", referencedColumnName="ID", nullable=false)
* })
*
*/
private $author;
/**
* #var \DateTime
*
* #ORM\Column(name="CREATED_ON", type="datetime", nullable=false)
*/
private $createdOn;
/**
* The default status of new pages is published
*
* #var string
*
* #ORM\Column(name="STATUS", type="string", nullable=false, )
*/
private $status = 'published';
/**
* Page constructor.
*/
public function __construct( ) {
//https://knpuniversity.com/screencast/collections/many-to-many-setup#doctrine-arraycollection
$this->allowedRoles = new ArrayCollection();
$this->childrenPages = new ArrayCollection();
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param int $id
*/
public function setId( int $id )
{
$this->id = $id;
}
/**
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* #param string $title
*/
public function setTitle( string $title )
{
$this->title = $title;
}
/**
* #return string
*/
public function getContentType()
{
return $this->contentType;
}
/**
* #param string $contentType
*/
public function setContentType( string $contentType )
{
$this->contentType = $contentType;
}
/**
* #return Page
*/
public function getParentPage()
{
return $this->parentPage;
}
/**
* #param Page $parentPage
*/
public function setParentPage( Page $parentPage )
{
$this->parentPage = $parentPage;
}
/**
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* #param string $content
*/
public function setContent( string $content )
{
$this->content = $content;
}
/**
* #return ArrayCollection|Role[]
*/
public function getAllowedRoles()
{
return $this->allowedRoles;
}
/**
* #param arrayCollection $allowedRoles
*/
public function setAllowedRoles( $allowedRoles )
{
$this->allowedRoles = $allowedRoles;
}
/**
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* #param string $slug
*/
public function setSlug( string $slug )
{
$this->slug = $slug;
}
/**
* #return string
*/
public function getPermalink()
{
return $this->permalink;
}
/**
* #param string $permalink
*/
public function setPermalink( string $permalink )
{
$this->permalink = $permalink;
}
/**
* #return User
*/
public function getAuthor()
{
return $this->author;
}
/**
* #param FacetUser $author
*/
public function setAuthor( User $author )
{
$this->author = $author;
}
/**
* #return \DateTime
*/
public function getCreatedOn()
{
return $this->createdOn;
}
/**
* #param \DateTime $createdOn
*/
public function setCreatedOn( \DateTime $createdOn )
{
$this->createdOn = $createdOn;
}
/**
* #return string
*/
public function getStatus()
{
return $this->status;
}
/**
* #param string $status
*/
public function setStatus( string $status )
{
$this->status = $status;
}
/**
* #return ArrayCollection
*/
public function getChildrenPages()
{
return $this->childrenPages;
}
/**
* #param ArrayCollection $childrenPages
*/
public function setChildrenPages( $childrenPages )
{
$this->childrenPages = $childrenPages;
}
/**
* Get the name of the node
*
* Each child of a node must have a unique name
*
* #return string
*/
public function getName() {
return $this->title;
}
/**
* Get the options for the factory to create the item for this node
*
* #return array
* #throws \Exception
*/
public function getOptions() {
if($this->contentType == 'page'){
return [
'route' => 'core_page_id',
'routeParameters' => ['id'=>$this->id]
];
}
if($this->contentType == 'doc'){
return [
'uri'=>'/'.$this->getContent()
];
}
if($this->contentType == 'link'){
return [
'uri'=>$this->content
];
}
throw new \Exception('No valid options found for page type',500);
}
/**
* Get the child nodes implementing NodeInterface
*
* #return \Traversable
*/
public function getChildren() {
return $this->getChildren();
}
}
The main difference here is that it implements Knp's NodeInterface and its functions which are defined at the end of the entity, getName(), getOptions(), and getChildren().
Now on to my Builder, which basically does the same thing as your recursive function.
<?php
namespace AppBundle\Menu;
use AppBundle\Entity\Page;
use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
class Builder implements ContainerAwareInterface
{
use ContainerAwareTrait;
/** #var ItemInterface */
private $menu;
/**
* #param FactoryInterface $factory
* #param array $options
*
* #return ItemInterface
*/
public function mainMenu(FactoryInterface $factory, array $options)
{
$this->menu = $factory->createItem('root');
$this->menu->addChild('Home', array('route' => 'core_homepage'));
$em = $this->container->get('doctrine')->getManager();
// get all published pages
$pages = $em->getRepository(Page::class)->findBy(['status'=>'published']);
// build pages
try {
$this->buildPageTree( $pages );
} catch ( \Exception $e ) {
error_log($e->getMessage());
}
return $this->menu;
}
/**
*
* #param array $pages
* #param Page $parent
* #param MenuItem $menuItem
*
* #throws \Exception
*/
private function buildPageTree(array $pages, $parent = null, $menuItem = null)
{
/** #var Page $page */
foreach ($pages as $page) {
// If page doesn't have a parent, and no menuItem was passed then this is a top level add.
if(empty($page->getParentPage()) && empty($menuItem) )
$parentMenu = $this->menu->addChild($page->getTitle(), $page->getOptions());
// if the current page's parent is === supplied parent, go deeper
if ($page->getParentPage() === $parent) {
// if a menuItem was given, then this page is a child so added it to the provided menu.
if(!empty($menuItem))
$parentMenu = $menuItem->addChild($page->getTitle(), $page->getOptions());
// go deeper
$this->buildPageTree($pages, $page, $parentMenu);
}
}
}
}
I hope this helps in some way!

SonataAdminBundle configureFormFields with two step relationated entities

I have the next entities
AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* #ORM\Table(name="fos_user_user")
*
*/
class User extends BaseUser
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="SmsHistory", mappedBy="user", cascade={"persist"}, orphanRemoval=true)
*/
private $smsHistory;
public function __construct()
{
parent::__construct();
$smsHistory = new ArrayCollection;
}
/**
* Get id
*
* #return int $id
*/
public function getId()
{
return $this->id;
}
/**
* #param \Doctrine\Common\Collections\ArrayCollection $smsHistory
*/
public function setSmsHistory($smsHistory){
if (count($smsHistory) > 0) {
foreach ($smsHistory as $i) {
$this->addSmsHistory($i);
}
}
return $this;
}
/**
* Add smsHistory
*
* #param \AppBundle\Entity\SmsHistory $smsHistory
*
* #return User
*/
public function addSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)
{
$smsHistory->setUser($this);
$this->smsHistory->add($smsHistory);
}
/**
* Remove smsHistory
*
* #param \AppBundle\Entity\SmsHistory $smsHistory
*/
public function removeSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)
{
$this->smsHistory->removeElement($smsHistory);
}
/**
* Get smsHistory
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSmsHistory()
{
return $this->smsHistory;
}
AppBundle/Entity/SmsHistory.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* SmsHistory
*
* #ORM\Table(name="sms_history")
* #ORM\Entity(repositoryClass="AppBundle\Repository\SmsHistoryRepository")
*/
class SmsHistory
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="smsHistory")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity="Contact", inversedBy="smsHistory")
* #ORM\JoinColumn(name="contact_id", referencedColumnName="id")
*/
private $contact;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return SmsHistory
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set contact
*
* #param \AppBundle\Entity\Contact $contact
*
* #return SmsHistory
*/
public function setContact(\AppBundle\Entity\Contact $contact = null)
{
$this->contact = $contact;
return $this;
}
/**
* Get contact
*
* #return \AppBundle\Entity\Contact
*/
public function getContact()
{
return $this->contact;
}
AppBundle/SmsHistory/Contact.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Contact
*
* #ORM\Table(name="contact")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ContactRepository")
*/
class Contact
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="contact")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* #ORM\OneToMany(targetEntity="SmsHistory", mappedBy="contact", cascade={"persist"}, orphanRemoval=true)
*/
private $smsHistory;
public function __construct() {
$smsHistory = new ArrayCollection;
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return Contact
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Add smsHistory
*
* #param \AppBundle\Entity\SmsHistory $smsHistory
*
* #return User
*/
public function addSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)
{
$smsHistory->setContact($this);
$this->smsHistory->add($smsHistory);
}
/**
* Remove smsHistory
*
* #param \AppBundle\Entity\SmsHistory $smsHistory
*/
public function removeSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)
{
$this->smsHistory->removeElement($smsHistory);
}
/**
* Get smsHistory
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSmsHistory()
{
return $this->smsHistory;
}
All entities are relationed with others.
In my UserAdmin i added in configureFormFields the field for add Contact and for add SmsHistory:
->add('contact', 'sonata_type_collection', array(
'cascade_validation' => true,
'by_reference' => true,
), array(
'edit' => 'inline',
'inline' => 'table',
))
->add('pushHistory', 'sonata_type_collection', array(
'cascade_validation' => true,
'by_reference' => true,
), array(
'edit' => 'inline',
'inline' => 'table',
))
In SmsHistoryAdmin i added the Contact field, to select a Contact:
->add('contact','sonata_type_model')
When I add a SmsHistory from UserAdmin, I want to display only Contact relationated with the current User i am editing, but all Contact of all User are displayed.
How I can do this?
Thank you!
I got the solution, I hope help someone.
In SmsHistoryAdmin, change this line:
->add('contact','sonata_type_model', array())
With this:
->add('contact', null, [
'query_builder' => $this->getAllowedContactQueryBuilder(),
])
And add this functions:
/**
* #return \Doctrine\Common\Persistence\ObjectManager|object
*/
protected function getEntityManager()
{
return $this->getContainer()->get('doctrine')->getManager();
}
/**
* #return null|\Symfony\Component\DependencyInjection\ContainerInterface
*/
protected function getContainer()
{
return $this->getConfigurationPool()->getContainer();
}
/**
* #return mixed
*/
private function getAllowedContactQueryBuilder()
{
if (!$this->getSubject()) {
return null;
}
return $this->getContactRepository()
->getContactByUserQueryBuilder($this->getSubject()->getUser());
}
/**
* #return \Doctrine\Common\Persistence\ObjectRepository
*/
public function getContactRepository()
{
return $this->getEntityManager()->getRepository('AppBundle:Contact');
}
And now the entity is filtering the Contact relationated with User.

Upload file with Symfony 2 and Angular.js

I have reviewed official docs http://symfony.com/doc/2.8/cookbook/controller/upload_file.html and other topics, but can't find the solution
So, here is my angular action
$scope.uploadFile = function(files) {
var fd = new FormData();
fd.append("file", files[0]);
$http.put('/api/clients/' + id +'/files', fd, {
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(function(resp) {
$mdToast.show(
$mdToast.simple()
.textContent(resp.message)
.hideDelay(1500)
);
}).error(function(resp) {
$mdToast.show(
$mdToast.simple()
.textContent(resp.message)
.hideDelay(1500)
);
})
};
And my entity for upload files
namespace PT\HearingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Client
*
* #ORM\Entity(repositoryClass="PT\HearingBundle\Repository\ClientRepository")
* #ORM\Table(name="`client_uploads`")
*
* #package PT\HearingBundle\Entity
* #author Roman Lunin <roman.lunin#primary.technology>
*/
class ClientUploads
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups("list")
*/
protected $id;
/**
* #ORM\Column(type="string")
*
* #Assert\NotBlank(message="Please, upload the product brochure as a PDF file.")
* #Assert\File(mimeTypes={ "application/pdf" })
*/
private $files;
/**
* #ORM\ManyToOne(targetEntity="Client", inversedBy="files")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
* #JMS\Groups("list")
*
* #var Client
*/
protected $client;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get client
*
* #return Client
*/
public function getClient()
{
return $this->client;
}
/**
* Get files
*
* #return string
*/
public function getFiles()
{
return $this->files;
}
/**
* Set files
*
* #param string $files
*
* #return ClientUploads
*/
public function setFiles($files)
{
$this->files = $files;
return $this;
}
/**
* Set client
*
* #param int $client
* #return Client
*/
public function setClient($client)
{
$this->client = $client;
return $this;
}
}
It's form
class ClientUploadsType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('files')
->add('files', FileType::class)
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'PT\HearingBundle\Entity\ClientUploads'
));
}
}
And, well, I can't get what exactly I should put in my symfony controller, now it's looks like that and doesn't working at all.
public function putClientFilesAction(Request $request, $id)
{
$upload = new ClientUploads();
$form = $this->createForm(ClientUploadsType::class, $upload);
$form->handleRequest($request);
var_dump($request->files->get('file'));
exit;
$em = $this->getDoctrine()->getEntityManager();
if ( ! $form->isValid()) {
return new JsonResponse(array(
'message' => 'File is not valid'
), Response::HTTP_BAD_REQUEST);
}
$file = $upload->getFiles();
$fileName = md5(uniqid()) . '.' . $file->guessExtension();
$file->move(
$this->container->getParameter('files_directory'),
$fileName
);
$upload->setClient($id);
$upload->setFiles($fileName);
$em->flush();
return new JsonResponse(array(
'message' => 'File saved'
), Response::HTTP_OK);
}

SonataMediaBundle Many to Many extra field nothing work

Is there a way to handle on entity easily image with sonata media bundle?
I try all solution I find but nothing work....
Many problems :
- unable to delete image from collection
- unable to add more than one file each time
- unable to see thumbnails
This bundle is not easy to use, I think I will rewrite an another bundle I won't spend no more time.
I think I'm doing to the good thing :
<?php
namespace Immo\FichierBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Immeuble
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Immo\FichierBundle\Entity\ImmeubleRepository")
*/
class Immeuble
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="numero", type="integer")
*/
private $numero;
/**
* #var Immo\EtablissementBundle\Entity\Etablissement
*
* #ORM\OneToOne(targetEntity="Immo\EtablissementBundle\Entity\Etablissement", cascade={"persist"})
*/
private $agence;
/**
* #var Immo\FichierBundle\Entity\Adresse
*
* #ORM\OneToOne(targetEntity="Immo\FichierBundle\Entity\Adresse", cascade={"persist"})
*/
private $adresse;
/**
* #var string
*
* #ORM\Column(name="vente", type="string", length=255)
*/
private $vente;
/**
* #var string
*
* #ORM\Column(name="coproindiv", type="string", length=255)
*/
private $coproindiv;
/**
* #var string
*
* #ORM\Column(name="exregulier", type="string", length=255)
*/
private $exregulier;
/**
* #var string
*
* #ORM\OneToMany(targetEntity="Immo\FichierBundle\Entity\ImmeubleHasPhoto", mappedBy="immeuble",cascade={"all"})
* #ORM\OrderBy({"ordre"="ASC"})
*/
private $photos;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function __toString() {
return $this->getNumero().' '.$this->getAdresse();
}
/**
* Constructor
*/
public function __construct()
{
$this->photo = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set numero
*
* #param integer $numero
* #return Immeuble
*/
public function setNumero($numero)
{
$this->numero = $numero;
return $this;
}
/**
* Get numero
*
* #return integer
*/
public function getNumero()
{
return $this->numero;
}
/**
* Set agence
*
* #param Immo\EtablissementBundle\Entity\Etablissement $agence
* #return Immeuble
*/
public function setAgence(\Immo\EtablissementBundle\Entity\Etablissement $agence)
{
$this->agence = $agence;
return $this;
}
/**
* Get agence
*
* #return Immo\EtablissementBundle\Entity\Etablissement
*/
public function getAgence()
{
return $this->agence;
}
/**
* Set adresse
*
* #param Immo\FichierBundle\Entity\Adresse $adresse
* #return Immeuble
*/
public function setAdresse(\Immo\FichierBundle\Entity\Adresse $adresse)
{
$this->adresse = $adresse;
return $this;
}
/**
* Get adresse
*
* #return Immo\FichierBundle\Entity\Adresse
*/
public function getAdresse()
{
return $this->adresse;
}
/**
* Set vente
*
* #param string $vente
* #return Immeuble
*/
public function setVente($vente)
{
$this->vente = $vente;
return $this;
}
/**
* Get vente
*
* #return string
*/
public function getVente()
{
return $this->vente;
}
/**
* Set coproindiv
*
* #param string $coproindiv
* #return Immeuble
*/
public function setCoproindiv($coproindiv)
{
$this->coproindiv = $coproindiv;
return $this;
}
/**
* Get coproindiv
*
* #return string
*/
public function getCoproindiv()
{
return $this->coproindiv;
}
/**
* Set exregulier
*
* #param string $exregulier
* #return Immeuble
*/
public function setExregulier($exregulier)
{
$this->exregulier = $exregulier;
return $this;
}
/**
* Get exregulier
*
* #return string
*/
public function getExregulier()
{
return $this->exregulier;
}
/**
* Addphoto
*
* #param \Immo\FichierBundle\Entity\ImmeubleHasPhoto $photo
* #return Personne
*/
public function addPhotos(\Immo\FichierBundle\Entity\ImmeubleHasPhoto $photo)
{
$photo->setImmeuble($this);
$this->photos[] = $photo;
return $this;
}
/**
* Remove removePhoto
*
* #param \Immo\FichierBundle\Entity\ImmeubleHasPhoto $photo
*/
public function removePhotos(\Immo\FichierBundle\Entity\ImmeubleHasPhoto $photo)
{
$this->photos->removeElement($photo);
}
/**
* {#inheritdoc}
*/
public function setPhotos($photos)
{
$this->photos = new ArrayCollection();
foreach ($photos as $photo) {
$this->addPhoto($photo);
}
}
/**
* Get photo
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPhotos()
{
return $this->photos;
}
}
The admin class :
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->tab('Général')
->with('Général')
->add('numero')
->add('agence')
->add('adresse','sonata_type_model_list')
->add('vente')
->add('coproindiv')
->add('exregulier')
->end()
->end()
->tab('Photos')
->with('Liste photos')
->add('photos', 'sonata_type_collection', array(
'label' => false,
'type_options' => array('delete' => true),
'cascade_validation' => true,
'btn_add' => 'Ajouter une photo',
"required" => false
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'ordre'
)
)
->end()
->end()
;
}
The join entity :
<?php
namespace Immo\FichierBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* ImmeubleHasPhoto
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Immo\FichierBundle\Entity\ImmeubleHasPhotoRepository")
*/
class ImmeubleHasPhoto
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255,nullable=true)
*/
private $nom;
/**
* #var integer
* #ORM\Column(name="ordre", type="integer")
*/
private $ordre;
/**
* #ORM\ManyToOne(targetEntity="Immeuble", inversedBy="photos",cascade={"all"},fetch="LAZY")
* #ORM\JoinColumn(name="immeuble_id", referencedColumnName="id", nullable=false)
*/
private $immeuble;
/**
* #var \Application\Sonata\MediaBundle\Entity\Media
* #ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media",cascade={"all"},fetch="LAZY")
* #ORM\JoinColumn(name="photo_id", referencedColumnName="id", nullable=false)
*/
private $photo;
public function __construct() {
}
public function __toString() {
return $this->getNom();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function setImmeuble(\Immo\FichierBundle\Entity\Immeuble $immeuble)
{
$this->immeuble = $immeuble;
return $this;
}
/**
* Get Immeuble
*
* #return \Immo\FichierBundle\Entity\Immeuble
*/
public function getImmeuble()
{
return $this->immeuble;
}
/**
* Set photo
*
* #param string $photo
* #return Application\Sonata\MediaBundle\Entity\Media
*/
public function setPhoto(\Application\Sonata\MediaBundle\Entity\Media $photo=null)
{
$this->photo = $photo;
return $this;
}
/**
* Get photo
*
* #return Application\Sonata\MediaBundle\Entity\Media
*/
public function getPhoto()
{
return $this->photo;
}
/**
* Set nom
*
* #param string $nom
* #return ImmeubleHasPhoto
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set ordre
*
* #param integer $ordre
* #return ImmeubleHasPhoto
*/
public function setOrdre($ordre)
{
$this->ordre = $ordre;
return $this;
}
/**
* Get ordre
*
* #return integer
*/
public function getOrdre()
{
return $this->ordre;
}
}
And finally the admin class for my join entity :
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$link_parameters = array();
if ($this->hasParentFieldDescription()) {
$link_parameters = $this->getParentFieldDescription()->getOption('link_parameters', array());
}
if ($this->hasRequest()) {
$context = $this->getRequest()->get('context', null);
if (null !== $context) {
$link_parameters['context'] = $context;
}
}
$formMapper
->add('nom',null,array('label'=>'Titre'))
->add('photo','sonata_type_model_list', array('required' => false), array(
'link_parameters' => array('context' => 'Photos_immeuble')
))
->add('ordre','integer')
;
}
Is there something wrong? I've passe many day to find why I'm unable to attache image but I found nothing.... I really think this bundle isn't functionnal....
Thanks for your help.

How to save the accent character é as é in a mysql database when it is inserted in a form in Symfony2 ?

I would like to know how to save the accent character é as é in a mysql database when it is inserted in a form in Symfony2. The explanation is as below:
This the code of the form builder I have:
<?php
namespace Ikproj\GroupeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class MessagesType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('contenu','textarea', array('attr' => array('rows' => '6','cols' => '40')));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ikproj\GroupeBundle\Entity\Messages'
));
}
/**
* #return string
*/
public function getName()
{
return 'ikproj_groupebundle_messages';
}
}
This is the code of the entity belonged to the form builder above:
<?php
namespace Ikproj\GroupeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Messages
*
* #ORM\Table(name="messages")
* #ORM\Entity(repositoryClass="Ikproj\GroupeBundle\Entity\MessagesRepository")
*/
class Messages
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="actor", type="integer")
*/
private $actor;
/**
* #var integer
*
* #ORM\Column(name="subject", type="integer")
*/
private $subject;
/**
* #var string
*
* #ORM\Column(name="contenu", type="string")
*/
private $contenu;
/**
* #var string
*
* #ORM\Column(name="status", type="string", length=10)
*/
private $status;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=10)
*/
private $type;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set actor
*
* #param integer $actor
* #return Messages
*/
public function setActor($actor)
{
$this->actor = $actor;
return $this;
}
/**
* Get actor
*
* #return integer
*/
public function getActor()
{
return $this->actor;
}
/**
* Set subject
*
* #param integer $subject
* #return Messages
*/
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
/**
* Get subject
*
* #return integer
*/
public function getSubject()
{
return $this->subject;
}
/**
* Set contenu
*
* #param string $contenu
* #return Messages
*/
public function setContenu($contenu)
{
$this->contenu = $contenu;
return $this;
}
/**
* Get contenu
*
* #return string
*/
public function getContenu()
{
return $this->contenu;
}
/**
* Set status
*
* #param string $status
* #return Messages
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return string
*/
public function getStatus()
{
return $this->status;
}
/**
* Set type
*
* #param string $type
* #return Messages
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return string
*/
public function getType()
{
return $this->type;
}
}
This is the code of the controller I have:
public function SendMessageAction(Request $request, $actor, $subject, $cible) {
$message = new Messages();
$form = $this->createForm(new MessagesType(), $message);
$em = $this->getDoctrine()->getManager();
$actor1 = $actor;
$subject1 = $subject;
$status1 = "unseen";
$cible1 = $cible;
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid()) {
$message->setActor($actor1);
$message->setSubject($subject1);
$message->setStatus($status1);
$message->setType($cible1);
$em->persist($message);
$em->flush();
return $this->redirect($this->generateUrl('task_success'));
}
}
else {
return $this->render('IkprojGroupeBundle:Messages:SendMessage.html.twig', array(
'form' => $form->createView(),
'actor' => $actor,
'subject' => $subject,
'cible' => $cible
));
}
}
And this is the code of the file config.yml belonged to the doctrine configuration:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
The problem is that when I insert the accent character é in the form then I valid, it will be saved in the database as é not é as you can see in screenshot below:
Whereas when I run the code below in Symfony2:
<?php
$tab = $_REQUEST['table'];
$a = $tab[0];
$b = $tab[1];
$con=mysqli_connect("localhost","root","","wkayetdb");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"INSERT INTO messages(actor,subject,contenu,status,type) VALUES ($a,$b,'é','unseen','G')");
mysqli_close($con);
?>
it works correctly and the character é will be saved as é as you can see below:
So, my questions are:
What is wrong in my code?
How can I save é as é in a mysql database once it is inserted in a form in Symfony2 ?
I do not know why you want to do that
but if you want to do this, simply comment that line "charset: UTF8"
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
# charset: UTF8

Resources