How add html element to the form field. How? The reasoning below is wrong, because it outputs my div in the "input" field, instead of inserting pure html between form fields. I want instead of input, to display html code, which would load images. I mean i have ManyToMany relation between images and users. When i have data transformer, which generates strings:
"<img src=\"{{ asset( 'bundles/meeting/images/uploads/".$img->getPath()."') }}\" height=\"200\" />". I would like to insert these strings between User form fields, which should finally display images.
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Entity\User.php
/**
* User
*
* #ORM\Table(name="tuser")
* #ORM\Entity()
*/
class User implements AdvancedUserInterface, \Serializable
...
/**
* #ORM\ManyToMany(targetEntity="\MeetingBundle\Entity\Image")
* #ORM\JoinTable(name="tUserImgUni",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="image_id", referencedColumnName="id")}
* )
*/
private $imgsuni;
....
/**
* Constructor
*/
public function __construct()
{
$this->imgsuni = new ArrayCollection();
}
...
/**
* Add imgsuni
*
* #param \MeetingBundle\Entity\Image $imgsuni
*
* #return User
*/
public function addImgsuni(\MeetingBundle\Entity\Image $image)
{
$this->imgsuni[] = $image;
return $this;
}
....
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Entity\Image.php
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class Image
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
...
/**
* Get path
*
* #return string
*/
public function getPath()
{
return $this->path;
}
..
/**
* Called after entity persistence
*
* #ORM\PostPersist()
* #ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
$this->file->move(
'C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\web\bundles\meeting\images\uploads',
$this->path
);
$this->file = null;
}
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Form\UserType.php
...
use MeetingBundle\Form\DataTransformer\ImageDataTransformer;
class UserType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$em = $options['em'];
$trans = new ImageDataTransformer($em);
$builder
->add('username')
->add(
$builder
->create('imgsuni', 'text')
->addModelTransformer($trans)
)
...
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MeetingBundle\Entity\User'
))
->setRequired(['em'])
->setAllowedTypes('em', 'Doctrine\ORM\EntityManager')
;
}
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Form\DataTransformer\ImageDataTransformer.php
<?php
namespace MeetingBundle\Form\DataTransformer;
use MeetingBundle\Entity\Image;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\DataTransformerInterface;
class ImageDataTransformer implements DataTransformerInterface
{
/**
* #var EntityManager
*/
private $em;
/**
* #param EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* Transforms an objects (Tags) to a string.
*/
public function transform($imgs)
{
if (null === $imgs) {
return "";
}
$output = [];
foreach ($imgs as $img) {
$output[] =
"<img src=\"{{ asset( 'bundles/meeting/images/uploads/".$img->getPath()."') }}\" height=\"200\" />"
;
}
return join(', ', $output);
}
}
For instance i have user with id=21 and image id=1.
My transformer generates string:
<img src="{{ asset( 'bundles/meeting/images/uploads/a4d7fb6b1282815d41e2015bfe6b3334f0833063.png') }}" height="200" />
i want that this string would be inserted as html code instead of beeing displayed in input of the form.
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Controller\UserController.php
/**
* Displays a form to edit an existing User entity.
*
* #Route("/{id}/edit", name="user_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, User $user)
{
$em = $this->getDoctrine()->getManager();
$deleteForm = $this->createDeleteForm($user);
$editForm = $this->createForm(new UserType(), $user, ['em' => $em ]);
$editForm->add('submit', 'submit', array(
'label' => 'Update details',
));
$image = new Image();
$imageForm=$this->createForm(new ImageType(), $image);
$imageForm->add('submit', 'submit', array('label' => 'Upload image'));
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
$imageForm->handleRequest($request);
if ($imageForm->isSubmitted() && $imageForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($image);
$em->flush();
//$image_id=$image->getId();
$user->addImgsuni($image);
$em->persist($user);
$em->flush(); //MeetingBundle::
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
return $this->render('MeetingBundle::user/edit.html.twig', array(
'user' => $user,
'edit_form' => $editForm->createView(),
'image_form' => $imageForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Resources\views\Image\edit.html.twig
{% extends "MeetingBundle::layout.html.twig" %}
{% block body %}
<h1>User edit</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
{{ form_end(edit_form) }}
<br>
{{ form(image_form) }}
<ul>
<li>
Back to the list
</li>
<br>
<li>
{{ form_start(delete_form) }}
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}
url: http://localhost:8000/user/21/edit
This displays form with Imgsuni input field with the following content:
<img src="{{ asset( 'bundles/meeting/images/uploads/a4d7fb6b1282815d41e2015bfe6b3334f0833063.png') }}" height="200" />
The way is to add html to some field in Image entity, said named "htmlimg". Than to display contents of the field in twig template using {{ image.htmlimg }}. This generates: <img src="{{ asset( 'bundles/meeting/images/uploads/a4d7fb6b1282815d41e2015bfe6b3334f0833063.png') }}" height="200" /> and displays images.
Related
I have setup a custom total "oversized_shipping_fee" however I am not able to set the title in the js totals object for some reason as seen below:
my code is as follows:
class OversizedShippingFee extends AbstractTotal
{
/**
* #var Client
*/
private $client;
/**
* OversizedShippingFee constructor.
* #param Client $client
*/
public function __construct(Client $client)
{
$this->_code ='oversized_shipping_fee';
$this->client = $client;
$this->_getTotal()->se
}
/**
* #param Quote $quote
* #param ShippingAssignmentInterface $shippingAssignment
* #param Total $total
* #return $this|AbstractTotal
*/
public function collect(Quote $quote, ShippingAssignmentInterface $shippingAssignment, Total $total)
{
/** #var \Magento\Quote\Model\Quote\Address $address */
$address = $shippingAssignment->getShipping()->getAddress();
if ($address->getAddressType() === \Magento\Quote\Model\Quote\Address::ADDRESS_TYPE_SHIPPING) {
$feeObject = $this->getFee($quote);
$fee = $feeObject->getData('price') ?: 0.0;
$total->setTotalAmount($this->getCode(), $fee);
$total->setBaseTotalAmount($this->getCode(), $fee);
$quote->setData('oversized_shipping_fee', $fee);
$quote->setData('oversized_shipping_fee_code', $feeObject->getData('code'));
$quote->setData('oversized_shipping_fee_title', 'test');
}
return $this;
}
/**
* #param Quote $quote
* #param Total $total
* #return array
*/
public function fetch(Quote $quote, Total $total)
{
$fee = $this->getFee($quote)->getData('price');
$sku = $this->getFee($quote)->getData('description');
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/total_segment.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($sku);
return [
'code' => $this->getCode(),
'value' => $fee,
'title' => 'test'
] ;
}
/**
* #param Quote $quote
* #return DataObject
*/
private function getFee(Quote $quote): DataObject
{
$request = $this->client->createRequest();
$request->initRequest($quote);
try {
return $this->client->send($request)->getOversizedShippingFee();
} catch (ApiException $ignore) {
return new DataObject();
}
}
}
the value of title attribute is null here, and I am not sure how to change it or how to add a new key-value pair such as "sku": "SKU-vale"
Firstly verify sales.xml that you have define proper total in the quote section quote and add fees
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
<section name="quote">
<group name="totals">
<item name="fees" instance="VL\Checkout\Total\Quote\OversizedShippingFee" sort_order="150"/>
</group>
</section>
<section name="order_invoice">
<group name="totals">
<item name="fees" instance="VL\Checkout\Total\Invoice\OversizedShippingFee" sort_order="150"/>
</group>
</section>
<section name="order_creditmemo">
<group name="totals">
<item name="fees" instance="VL\Checkout\Total\Creditmemo\OversizedShippingFee" sort_order="150"/>
</group>
</section>
</config>
Also, make sure to load module after checkout for that add sequence in the module.xml and then run setup upgrade to update the module dependency.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="VL_Checkout" setup_version="1.0.0" schema_version="1.0.0">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Quote"/>
<module name="Magento_Checkout"/>
</sequence>
</module>
</config>
please add the getLabel() method in the OversizedShippingFee file
<?php
namespace VL\Checkout\Total\Quote;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Quote\Api\Data\ShippingAssignmentInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Address\Total;
use Magento\Quote\Model\Quote\Address\Total\AbstractTotal;
use VL\Checkout\Helper\Data;
use Magento\Framework\App\Helper\Context;
class OversizedShippingFee extends AbstractTotal
{
/**
* #var PriceCurrencyInterface
*/
protected $_priceCurrency;
protected $_helper;
/**
* #param PriceCurrencyInterface $priceCurrency
*/
public function __construct(
PriceCurrencyInterface $priceCurrency,
Data $helper,
Context $context
) {
$this->_priceCurrency = $priceCurrency;
$this->_helper = $helper;
$this->scopeConfig = $context->getScopeConfig();
}
/**
* #param Quote $quote
* #param ShippingAssignmentInterface $shippingAssignment
* #param Total $total
*
* #return $this|bool
*/
public function collect(
Quote $quote,
ShippingAssignmentInterface $shippingAssignment,
Total $total
) {
parent::collect($quote, $shippingAssignment, $total);
$address = $shippingAssignment->getShipping()->getAddress();
if ($address->getAddressType() === \Magento\Quote\Model\Quote\Address::ADDRESS_TYPE_SHIPPING) {
$baseFees = $this->getFee($quote);
$fee = $this->_priceCurrency->convert($fee);
$total->addTotalAmount($this->getCode(), $fee);
$total->addBaseTotalAmount($this->getCode(), $baseFees);
$total->setBaseGrandTotal($total->getBaseGrandTotal() + $baseFees);
}
return $this;
}
/**
* #param Quote $quote
* #param Total $total
* #return array
*/
public function fetch(Quote $quote, Total $total)
{
$amount = $total->getFee();
if ($amount == 0) {
$amount = $quote->getFee();
}
$title = $this->getLabel();
return [
'code' => $this->getCode(),
'title' => $title,
'value' => $amount
];
}
/**
* Get label
*
* #return \Magento\Framework\Phrase
*/
public function getLabel()
{
return __('test');
}
}
in the js file you can console.log the totals.getSegment('fees')
and display the text in html
fees.html
<!-- ko -->
<tr class="totals fee excl">
<th class="mark" scope="row">
<span class="label" data-bind="text: title"></span>
<span class="value" data-bind="text: getValue()"></span>
</th>
<td class="amount">
<span class="price"
data-bind="text: getValue(), attr: {'data-th': title}"></span>
</td>
</tr>
<!-- /ko -->
I have in my patient space, a list of doctors with whom he has made an appointment.And next to each doctor, I want to add a button I like so that the patient can tell if he liked or not the consultation with the doctor.
And I would like to know the number of patients who have liked a given doctor. For this number to be displayed in the doctor's details.
Here is my controller where I have my list of doctors
Controller
public function patientBookingListAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$medecin = $em->getRepository("DoctixMedecinBundle:Medecin")->findOneBy(array(
'user' => $this->getUser(),
));
$patient = $em->getRepository("DoctixPatientBundle:Patient")->findOneBy(array(
'user' => $this->getUser(),
));
$bookings = $em->getRepository("DoctixFrontBundle:Booking")->findBy(array(
"patient" => $patient
));
$bookings = $this->get('knp_paginator')->paginate($bookings, $request->query->get('page', 1), 3);
return $this->render('DoctixPatientBundle:Patient:bookings.html.twig', array(
'bookings' => $bookings
));
}
I had already create my table favorite_doctor :
Entity favorite_doctor
class MedecinFavoris
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Doctix\PatientBundle\Entity\Patient", inversedBy="medecin_favoris")
* #ORM\JoinColumn(name="patient_id", referencedColumnName="id")
*/
private $patient;
/**
* #ORM\ManyToOne(targetEntity="Doctix\MedecinBundle\Entity\Medecin", inversedBy="medecin_favoris")
* #ORM\JoinColumn(name="medecin_id", referencedColumnName="id")
*/
private $medecin;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set patient
*
* #param \Doctix\PatientBundle\Entity\Patient $patient
*
* #return MedecinFavoris
*/
public function setPatient(\Doctix\PatientBundle\Entity\Patient $patient = null)
{
$this->patient = $patient;
return $this;
}
/**
* Get patient
*
* #return \Doctix\PatientBundle\Entity\Patient
*/
public function getPatient()
{
return $this->patient;
}
/**
* Set medecin
*
* #param \Doctix\MedecinBundle\Entity\Medecin $medecin
*
* #return MedecinFavoris
*/
public function setMedecin(\Doctix\MedecinBundle\Entity\Medecin $medecin = null)
{
$this->medecin = $medecin;
return $this;
}
/**
* Get medecin
*
* #return \Doctix\MedecinBundle\Entity\Medecin
*/
public function getMedecin()
{
return $this->medecin;
}
}
I would like that when I click on the button like that my data is saved in this table.
Twig
{% for booking in bookings %}
<div class="list_general" id="liste">
<ul>
<li>
<figure><img src="{{ vich_uploader_asset(booking.medecin.media, 'imageFile') }}"
alt="{{ booking.medecin.media.imagename }}"></figure>
<h4>Dr. {{ booking.medecin.user.prenom|capitalize }} {{ booking.medecin.user.nom|upper }} <i class="pending">Pending</i></h4>
<ul class="booking_details">
<li><strong>Date et heure</strong>{{ booking.dateHeureRdv|date('d/m/Y') }}</li>
<li><strong>Heure</strong>{{ booking.dateHeureRdv|date('H:i') }}</li>
<li><strong>Motif</strong>Consultation</li>
<li><strong>Téléphone</strong>{{ booking.medecin.user.numTel }}</li>
<li><strong>Email</strong>{{ booking.medecin.user.username }}</li>
</ul>
<ul class="buttons">
<li><i class="fa fa-fw fa-check-circle-o"></i> Déplacer Rdv</li>
<li><i class="fa fa-fw fa-times-circle-o"></i> Annuler</li>
</ul>
</li>
<div class="like">
Like
</div>
</ul>
</div>
{% endfor %}
Now i do not know exactly what to do when i click the like button. Knowing that when a patient like, the data must register in the database and the like button must also disappear to no longer allow him to vote two or more times.
Thanks a lot
Hello dear i have an problem when user need too delete or edit post , laravel show error " you can't edit post ... " i use a model and controller in laravel and user "auth" system id for access post for delete or edit now see my work :
Index View
#extends('layouts.app')
#section('content')
#auth
<h6 class="alert alert-dark">Dear Guest {{ Auth::user()->name }} for send a post <a class="btn btn-success" href="{{ route('ads.create') }}">Click</a> Here</h6>
#endauth
#guest
<div class="alert alert-primary">for send a post you can <a class="btn btn-success" href="{{ route('register') }}">Register</a></div>
#endguest
#if(count($adses) > 0)
<div class="row">
#foreach($adses as $ads)
<div class="col-xl-3 col-lg-3 col-md-6 col-sm-12">
<div class="card mb-4">
<img class="card-img-top img-fluid" src="/storage/cover_images/{{$ads->cover_image}}" alt="Card image cap">
<div class="card-body">
<h6 class="card-title">{{ $ads->title }}</h6>
#if(!Auth::guest())
#if(Auth::user()->id == $ads->user_id)
<div class="row">
{!!Form::open(['action' => ['AdsController#destroy', $ads->id], 'method' => 'POST',]) !!}
{{Form::hidden('_method', 'DELETE')}}
{{Form::submit('Delete', ['class' => 'btn btn-danger'])}}
{!!Form::close() !!}
Edit
</div>
#endif
#endif
</div>
</div>
</div>
#endforeach
{{ $adses->links() }}
#else
<p class="alert alert-warning" role="alert">any post !</p>
</div>
#endif
#endsection
Ads Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Ads extends Model
{
protected $table = 'ads';
public $primaryKey = 'id';
public $timestamps = true;
public function user(){
return $this->belongsTo('App\User');
}
}
User model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function adses(){
return $this->hasMany('App\Ads');
}
}
Ads Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Ads;
class AdsController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$adses = Ads::orderBy('created_at', 'desc')->paginate(16);
return view('ads.index')->with('adses', $adses);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('ads.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'body' => 'required',
'adsType' => 'required',
'cover_image' => 'image|nullable|max:1999',
]);
// Handle File Upload
if($request->hasFile('cover_image')){
// Get filename with the extension
$filenameWithExt = $request->file('cover_image')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just ext
$extension = $request->file('cover_image')->getClientOriginalExtension();
// Filename to store
$fileNameToStore= $filename.'_'.time().'.'.$extension;
// Upload Image
$path = $request->file('cover_image')->storeAs('public/cover_images', $fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
$ads = new Ads();
$ads->title = $request->input('title');
$ads->body = $request->input('body');
$ads->adsType = $request->input('adsType');
$ads->user_id = auth()->user()->id;
$ads->cover_image = $fileNameToStore;
$ads->save();
return redirect('/home')->with('success', 'آگهی شما با موفقیت درج شد .');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$ads = Ads::find($id);
return view('ads.show')->with('ads', $ads);
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Ads $ads
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
$ads = Ads::find($id);
if(auth()->user()->id !== $ads->user_id){
return redirect('/')->with('error', 'you cant edit other user's post');
}
return view('ads.edit')->with('ads', $ads);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Ads $ads
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'title' => 'required',
'body' => 'required',
'adsType' => 'required',
'cover_image' => 'required',
]);
// Handle File Upload
if($request->hasFile('cover_image')){
// Get filename with the extension
$filenameWithExt = $request->file('cover_image')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just ext
$extension = $request->file('cover_image')->getClientOriginalExtension();
// Filename to store
$fileNameToStore= $filename.'_'.time().'.'.$extension;
// Upload Image
$path = $request->file('cover_image')->storeAs('public/cover_images', $fileNameToStore);
}
$ads = Ads::find($id);
$ads->title = $request->input('title');
$ads->body = $request->input('body');
$ads->adsType = $request->input('adsType');
if($request->hasFile('cover_image')){
$ads->cover_image = $fileNameToStore;}
$ads->save();
return redirect('/')->with('success', 'your post is update');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$ads = Ads::find($id);
if(auth()->user()->id !== $ads->user_id){
return redirect('/')->with('error', 'you cant delete other user's post');
}
if($ads->cover_image != 'noimage.jpg'){
// Delete Image
Storage::delete('public/cover_images/'.$ads->cover_image);
}
$ads->delete();
return redirect('/')->with('success', 'Post Removed');
}
}
Routs
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('/', 'AdsController');
Route::resource('ads', 'AdsController');
now , after send a post and login in system user cant delete or edit her post .
Thank you
auth()->user()->id !== $ads->user_id .
Уou have this line. And if user not login when he creating post, you are will be have user_id == null. Check in DB than user_id?
I solved my problem
if(auth()->user()->id !== $ads->user_id)
Since you're using !==, make sure your user_id is integer
I am new with Symfony 3 and I am implementing a simple web application. I'm trying to get data from FORM but when get the request and put data in Entity manager instance I got a error, let me explain with code:
This is the Controller (DefaultController)
namespace Database\TestBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Database\TestBundle\Entity\Products;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class DefaultController extends Controller
{
public function addAction(Request $request)
{
$product = new Products();
$form = $this->createFormBuilder($product)
->add('name', TextType::class)
->add('price', TextType::class)
->add('description', TextareaType::class)
->add('save', SubmitType::class, array('label' => 'Save Product'))
->getForm();
$form->handleRequest($request);
if($form->isValid())
{
$product = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em-flush(); //I got the error in this line
return $this->redirect($this->generateUrl('database_test_list'));
}
return $this->render('DatabaseTestBundle:Default:add.html.twig', array(
'form' => $form->createView()));
}
}
This is my Entity (Products)
namespace Database\TestBundle\Entity;
/**
* Products
*/
class Products
{
/**
* #var int
*/
private $id;
/**
* #var string
*/
private $name;
/**
* #var int
*/
private $price;
/**
* #var string
*/
private $description;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Products
*/
public function setName($name)
{
$this->name= $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* #param integer $price
*
* #return Products
*/
public function setPrice($price)
{
$this->price= $price;
return $this;
}
/**
* Get price
*
* #return int
*/
public function getPrice()
{
return $this->price;
}
/**
* Set description
*
* #param string $description
*
* #return Products
*/
public function setDescription($description)
{
$this->description= $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
This is my View (add)
{% extends '::frontend.html.twig' %}
{% block title %}List of Products{% endblock %}
{% block body %}
<h1 class="clase">Add Product</h1>
<hr>
Return to list
<br/>
<br/>
{{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }}
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-sm-1 control-label required" for="form_name">Name</label>
<div class="col-sm-3">
{{form_widget(form.name, {'attr': {'class': 'form-control col-md-12'}})}}
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label required" for="form_price">Price</label>
<div class="col-sm-3">
{{form_widget(form.price, {'attr': {'class': 'form-control col-md-12'}})}}
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label required" for="form_description">Description</label>
<div class="col-sm-3">
{{form_widget(form.description, {'attr': {'class': 'form-control col-md-12'}})}}
</div>
</div>
<hr/>
{{form_widget(form.save, {'attr': {'class': 'btn btn-default'}})}}
</p>
</div>
</div>
{{ form_end(form) }}
{% endblock %}
And this is the Error Message:
Stack Trace
in src\Database\TestBundle\Controller\DefaultController.php at line 48
46 $em = $this->container->get('doctrine')->getManager();
47 $em->persist($product);
48 $em-flush();
49 return $this->redirect($this->generateUrl('database_test_list'));
at ErrorHandler ->handleError ('8', 'Object of class Doctrine\ORM\EntityManager could not be converted to int',
'C:\xampp\htdocs\taller_symfony\src\Database\TestBundle\Controller\DefaultController.php', '48', array('request' => object(Request), 'producto' => object(Productos), 'form' => object(Form), 'em' => object(EntityManager)))
in src\Database\TestBundle\Controller\DefaultController.php at line 48
Somebody has any idea regarding this error?? Anyone can give me a hand with this please, thanks a lot.
You have syntax error, which is > sign missing.
You have:
$em-flush();
while it should be:
$em->flush();
PHP didn't throw syntax error because it's actually correct PHP syntax, but not the one that you were expected it to be. You tried to make arithmetical (subtraction) operation on object.
I have 3 entities: Company, Industry, Category
I would like to create a form where the user can input the name of the company and then selects the Industry from a dropdown list. Every Industry has Categories. When user selects a Industry I want to populate the Category list. I've read following article: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data
I've created the form but when the ajax call is triggered I get following error:
Neither the property "categories" nor one of the methods "setCategories()", "__set()" or "__call()" exist and have public access in class "ebulucu\MainBundle\Entity\Company"
I'm on this now many days and just can't get it work. I hope somebody have some hints for me. I need a form with one input field for the company name, two dropdowns Industry and Category where Category depends on the selected Industry. Company has a ManyToMany relation to Category and Industry has a OneToMany relation too category. So far this is my code:
Edit:
I have tried the code with OneToMany instead ManyToMany relation between Company and Category.
That works fine. But what to do in case ManyToMany Relation? How to manage to load and set Categories?
my 3 entities:
class Company
{
/**
* #var integer
* #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;
/**
* #ORM\ManyToMany(targetEntity="Category", mappedBy="companies")
*/
private $categories;
/**
* Constructor
*/
public function __construct()
{
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
... setters and getters
class Industry
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=80)
* #Assert\NotBlank()
*/
private $name;
/**
* #var
*
* #ORM\OneToMany(targetEntity="Category",mappedBy="industry")
*/
private $categories;
public function __construct()
{
$this->categories = new ArrayCollection();
}
...setters and getters
class Category
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=80)
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="Industry", inversedBy="categories");
* #ORM\JoinColumn(name="industry_id", referencedColumnName="id",nullable=false)
*/
private $industry;
/**
* #ORM\ManyToMany(targetEntity="Company", inversedBy="categories");
* #ORM\JoinTable(name="categories_companies")
*/
private $companies;
... setters and getters
My Company Form Class:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use ebulucu\MainBundle\Entity\Industry;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Doctrine\ORM\EntityRepository;
class CompanyRegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('industry', 'entity', array(
'mapped' => false,
'class' => 'ebulucuMainBundle:Industry',
'property' => 'name',
'empty_value' => 'Choose industry',
));
$formModifier = function(FormInterface $form, $industry_id) {
if($industry_id) {
$form->add('categories', 'entity', array(
'class' => 'ebulucuMainBundle:Category',
'query_builder' => function(EntityRepository $er) use ($industry_id) {
$query = $er->createQueryBuilder('i')
->select(array('i'))
->where('i.industry_id = :industry_id')
->setParameter('industry_id', $industry_id)
->orderBy('i.name', 'ASC');
return $query;
},
'empty_value' => 'Choose category'
)
);
}
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifier) {
$formModifier($event->getForm(), null);
}
);
//** Checks for Industry that is submitted and adds categories based on industry selection **//
$builder->get('industry')->addEventListener(
FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formModifier) {
$industry_id = $event->getData();
$formModifier($event->getForm()->getParent(), $industry_id);
}
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ebulucu\MainBundle\Entity\Company',
));
}
public function getName()
{
return 'company';
}
}
The Controller:
use ebulucu\MainBundle\Entity\Company;
use ebulucu\MainBundle\Form\Type\CompanyRegistrationFormType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use ebulucu\MainBundle\Entity\Industry;
use ebulucu\MainBundle\Entity\Category;
use Symfony\Component\HttpFoundation\Request;
class MainController extends Controller
{
/**
* #Route("/", name="homepage")
* #Template()
*/
public function indexAction(Request $request)
{
$company = new Company();
$form = $this->createForm(new CompanyRegistrationFormType(), $company);
$form->handleRequest($request);
if ($form->isValid()) {
return $this->redirect($this->generateUrl('fos_user_security_login'));
}
return array(
'form' => $form->createView(),
);
}
/**
* #Route("/", name="loadIndustryCategories")
* #Template()
*/
public function loadIndustryCategories(Request $request)
{
$company = new Company();
$form = $this->createForm(new CompanyRegistrationFormType(), $company);
$form->handleRequest($request);
return array(
'form' => $form->createView(),
);
}
}
Twig Template with form and ajax call:
{% block content %}
<div>Homepage</div>
{{ form_start(form, {'attr': {'id': 'form_industry'}}) }}
{{ form_end(form) }}
{% endblock %}
{% block js%}
<script>
$('#company_industry').change( function() {
var postData = $("#form_industry").serializeArray();
var formURL = {{ path('loadIndustryCategories') }};
$.ajax(
{
url : formURL,
type: "POST",
data : postData,
success:function(data, textStatus, jqXHR)
{
//data: return data from server
},
error: function(jqXHR, textStatus, errorThrown)
{
//if fails
}
});
e.preventDefault(); //STOP default action
e.unbind(); //unbind. to stop multiple form submit.
});
</script>
{% endblock %}
Company:categories will be a collection of entities, not a singular entity, so it shouldn't have a setCategory method, otherwise you can inadvertently remove your whole collection. Instead you will have an addCategories, removeCategories and getCategories (this could be addCategorie and removeCategorie if doctrine generated due to its 'un-pluralization').
To fix, you need to change your categories form element to a type of collection instead of an entity in CompanyRegistrationFormType.
Just checking, should a company have one category or multiple? At the moment, your code seems to be somewhat a bit of both?