I want to retrieve a quantity for each item that I store in session and store it in database.
How do I retrieve the quantity in session and passed to my quantity attribute of my article entity during database persistence?
For example for this article:
(id 4, quantity 2).
I would store 2 in the quantity attribute of my article entity.
I tried :
$article->setQuantity($session->get('panier'));
I have this error:
An exception occurred while executing 'INSERT INTO article ....... {"4": "2"}
Notice: Array to string conversion
/**
* #Route("/payment", name="payment")
*/
public function paymentAction(Request $request)
{
$session = $request->getSession();
$produits = $this->getDoctrine()->getManager()->getRepository('AppBundle:Stock')->findArray(array_keys($session->get('panier')));
$commande = $session->get('commande');
var_dump($session->get('panier'));
if ($request->isMethod('POST')) {
$token = $request->get('stripeToken');
\Stripe\Stripe::setApiKey($this->getParameter("private_key"));
\Stripe\Charge::create(array(
"amount" => $commande->getTotal() * 100,
"currency" => "EUR",
"source" => $token,
"description" => ""
));
foreach ($produits as $produit) {
$article = new Article();
$article->setTitle($produit->getStock()->getTitle());
$article->setContent($produit->getStock()->getContent());
//problem here
$article->setQuantity($session->get('panier'));
//
$article->setPrice($produit->getPrice());
$commande->addArticle($article);
$em = $this->getDoctrine()->getManager();
$em->persist($commande);
$em->flush();
}
return $this->redirectToRoute('confirmation');
}
return $this->render(':default:payment.html.twig', array(
'commande' => $commande,
'panier' => $session->get('panier'),
'produits' => $produits,
'public_key' => $this->getParameter("public_key"),
));
}
Add article in session :
/**
* #Route("/shop/add/{id}", name="add_article")
*
*/
public function addArticlelAction(Request $request, $id)
{
$session = $request->getSession();
if (!$session->has('panier'))
$session->set('panier', array());
$panier = $session->get('panier');
if (array_key_exists($id, $panier)) {
if ($request->query->get('qte') != null)
$panier[$id] = $request->query->get('qte');
} else {
if ($request->query->get('qte') != null)
$panier[$id] = $request->query->get('qte');
else
$panier[$id] = 1;
}
$session->set('panier', $panier);
return $this->redirectToRoute('panier');
}
UPDATE:
If $id in addArticlelAction is the product id then:
foreach ($produits as $produit) {
$article = new Article();
$article->setTitle($produit->getStock()->getTitle());
$article->setContent($produit->getStock()->getContent());
//problem here
$article->setQuantity($session->get('panier')[$produit->getId()]);
//
$article->setPrice($produit->getPrice());
$commande->addArticle($article);
$em = $this->getDoctrine()->getManager();
$em->persist($commande);
$em->flush();
}
should work, because for the moment you have two products (product1 who has id 1 and product 4 who has id 4). When you call /shop/add/{id}, you are adding to $session->get('panier')[1] and $session->get('panier')[4] the quantities. So, when you're in foreach (to store in DB), you need to access index 1 and index 4 ($produit->getId())
Related
undefined variable company
undefined variable i m getting error
public function addPolicyAction()
{
if ($this->sessionContainer->empId == "")
{
return $this->redirect()->toRoute('admin_user_login');
}
$ouCode = $this->sessionContainer->ouCode;
$langCode = $this->sessionContainer->langCode;
$empId = $this->sessionContainer->empId;
$arrLabel = array('company_policy','pdid','pdname','file_name','active');
$commonTransalationLabel = $this->commonTranslation->getCommonTransactionInformation($arrLabel, $langCode);
$companyPolicyForm = new CompanyPolicyForm($commonTransalationLabel);
if ($this->getRequest()->isPost()) {
// $data = $this->params()->fromPost();
$request = $this->getRequest();
$data = array_merge_recursive(
$request->getPost()->toArray(), $request->getFiles()->toArray()
);
$data['ouCode'] = $ouCode;
$data['langCode'] = $langCode;
$companyPolicyForm->setData($data);
$chkValidate = $this->hrCompanypolicy->findBy([
'ouCode' => $this->sessionContainer->ouCode,
'langCode' => $this->sessionContainer->langCode
]);
if ($companyPolicyForm->isValid()) {
$data = $companyPolicyForm->getData();
if(isset($_POST['Submit'])){
$name = $_FILES['fileName']['name'];
$target_dir = 'public/media/policy_photos/';
$target_file = $target_dir . basename($_FILES["fileName"]["name"]);
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$extensions_arr = array("jpg","jpeg","png","gif");
if( in_array($imageFileType,$extensions_arr) ){
move_uploaded_file($_FILES['fileName']['tmp_name'],$target_dir.$name);
}
}
$company = $this->companyPolicyManager->add($data,$ouCode, $langCode,$empId);
$cpData = $this->companyPolicyManager->getcpDataBycpId($data,$ouCode,$langCode);
$companyPolicyForm->buildCompanyPolicyData($cpData);
$this->flashMessenger()->addMessage($commonTransalationLabel['success_message']);
}
}
return new ViewModel([
'form' => $company,
'companypolicydata' => $cpData,
'label' => $commonTransalationLabel,
'form' => $companyPolicyForm,
'flashMessages' => $this->flashMessenger()->getMessages()
]);
}
i want to remove undefined variable in zendframework 3
i m using zendframework 3 and getting undefined variable in zendframework 3 what is the issue in the code ?
How to defined a variable in zendframework 3 i want to solve the issue
Problem is that you're using the $company variable in your return new ViewModel statement, but you only create the variable when the entire form is valid.
Instead of what you're doing, make sure that you provide a Form instance (whichever you need, e.g. CompanyForm) to your controller via the Factory. Then have your function along the lines like below (I've removed some error checking):
public function editAction()
{
$id = $this->params()->fromRoute('id', null);
/** #var Company $entity */
$entity = $this->getObjectManager()->getRepository(Company::class)->find($id);
/** #var CompanyForm $form */
$form = $this->getForm();
$form->bind($entity);
/** #var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
/** #var Company $entity */
$entity = $form->getObject();
$this->getObjectManager()->persist($entity);
try {
$this->getObjectManager()->flush();
} catch (Exception $e) {
throw new Exception('Could not save. Error was thrown, details: ', $e->getMessage());
}
return $this->redirectToRoute('companies/view', ['id' => $entity->getId()]);
}
}
return [
'form' => $form,
];
}
I have a little problem. I have an object "persona" who has several collections.
I have a form who render all the collection and allow me to add and remove collections.
After that, I dump all the information and the object "persona" has all the collection I sent it when I submitted the form.
When I persist and flush the data, doctrine saves persona but not the collection
This are my configurations:
Entity persona
/**
* #ORM\OneToMany(targetEntity="PersonaDomicilio",mappedBy="idPersona",cascade={"persist"},orphanRemoval=true)
*/
private $domicilios;
public function __construct() {
$this->domicilios = new ArrayCollection();
}
public function getDomicilios() {
return $this->domicilios;
}
public function addDomicilio(PersonaDomicilio $persona_domicilio) {
$persona_domicilio->setIdPersona($this);
$this->domicilios[] = $persona_domicilio;
}
public function removeDomicilio(PersonaDomicilio $persona_domicilio) {
$this->domicilios->removeElement($persona_domicilio);
}
Entity PersonaDomicilio
/**
* #var \AppBundle\Entity\Persona
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Persona",inversedBy="domicilios")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_persona", referencedColumnName="id_persona")
* })
*/
private $idPersona;
The PersonaType
->add('domicilios', CollectionType::class, array(
'entry_type' => PersonaDomicilioType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'label' => false
))
The controller action
$em = $this->getDoctrine()->getManager();
$persona = new Persona();
$formulario = $this->createForm(
PersonaType::class,
$persona,
array('action' => $this->generateUrl('persona_create'),
'method' => 'POST')
);
$formulario->handleRequest($request);
$persona->setFisicaJuridica('F');
$em->persist($persona);
$em->flush();
I don´t wanna persist all the collection manually with a foreach, because the cascade persist would help to do that.
I have to say that I did several tests and I can´t understand why is not working.
Pd: "id_persona" is correctly setted to the collections too.
This is "normal". If you refer to this old symfony documentation (which is still valid), you also have to persist your PersonaDomicilio (see the paragraph Doctrine: Ensuring the database persistence).
Here is their example :
// src/Acme/TaskBundle/Controller/TaskController.php
use Doctrine\Common\Collections\ArrayCollection;
// ...
public function editAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$task = $em->getRepository('AcmeTaskBundle:Task')->find($id);
if (!$task) {
throw $this->createNotFoundException('No task found for id '.$id);
}
$originalTags = new ArrayCollection();
// Create an ArrayCollection of the current Tag objects in the database
foreach ($task->getTags() as $tag) {
$originalTags->add($tag);
}
$editForm = $this->createForm(new TaskType(), $task);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
// remove the relationship between the tag and the Task
foreach ($originalTags as $tag) {
if (false === $task->getTags()->contains($tag)) {
// remove the Task from the Tag
$tag->getTasks()->removeElement($task);
// if it was a many-to-one relationship, remove the relationship like this
// $tag->setTask(null);
$em->persist($tag);
// if you wanted to delete the Tag entirely, you can also do that
// $em->remove($tag);
}
}
$em->persist($task);
$em->flush();
// redirect back to some edit page
return $this->redirectToRoute('task_edit', array('id' => $id));
}
// render some form template
}
And here an example for your configuration (not tested)
<?php
// Create an ArrayCollection of the current domicilios objects in the database
$originalDomicilios = new ArrayCollection();
foreach ($persona->getDomicilios() as $domicilio) {
$originalDomicilios->add($domicilio);
}
// Check request
$form->handleRequest($request);
// Was the form submitted?
if ($form->isSubmitted() && $form->isValid()) {
try {
// Handle domicilios
foreach ($originalDomicilios as $domicilio) {
if (false === $persona->getDomicilios()->contains($domicilio)) {
// remove the persona from the domicilio (or remove it)
$domicilio->removePersona($persona);
// Persist domicilio
$em->persist($domicilio);
}
}
// Save new domicilios
foreach($persona->getDomicilios() as $domicilio){
if (false === $originalDomicilios->contains($domicilio)){
// Add persona
$domicilio->addPersona($persona);
// Persist domicilio
$em->persist($domicilio);
}
}
// Persist persona
$em->persist($persona);
// Save
$em->flush();
...
} catch (\Exception $e) {
}
}
I just start to study zend framwork2 , and read the document about how to use fieldset http://zf2.readthedocs.org/en/latest/modules/zend.form.collections.html
I can use tablegateway insert product data into database.but don't know how to insert data to brand table and I don't know how to link product and brand . thank you very much!!!!!
Many people has the same problem and rlandas wrote and uploaded a working code to github
i post the code of the controller in case the url changes. but take a look at the complete module in github
<?php
namespace Product\Controller;
use Product\Table\ProductTable;
use Product\Entity\Product as ProductEntity;
use Product\Form\CreateProduct;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Http\PhpEnvironment\Response;
use Zend\View\Model\ViewModel;
class ManageController extends AbstractActionController
{
public function indexAction ()
{
$product = $this->getProductTable();
$products = $product->getAllOrderByName();
$view = new ViewModel();
$view->setVariable('products', $products);
return $view;
}
public function viewAction ()
{
if ($id = $this->params('id')) {
$product = $this->getProductTable()
->getByProductId($id);
}
$view = new ViewModel();
$view->setVariable('product', $product);
return $view;
}
public function addAction ()
{
$form = new CreateProduct();
$product = $this->getServiceLocator()->get('Product\Entity\Product');
$form->bind($product);
$data = array(
'product' => array(
'name' => 'product name ' . mt_rand(1, 1000),
'price' => mt_rand(100.000, 5000.999) / 100,
'brand' => array(
'name' => 'My brand ' . mt_rand(1, 200),
'url' => 'http://www.mybrand.com'
),
'categories' => array(
array('name' => 'Sony'),
array('name' => 'Panasonic'),
array('name' => 'Phillips')
)
)
);
$form->populateValues($data);
// action viewscript
$view = new ViewModel(array(
'form' => $form
));
// do Post/Redirect/Get (PRG) strategy to stop user refresh/back button
$prg = $this->prg($this->getRequest()->getRequestUri(), true);
if ($prg instanceof Response) {
return $prg;
}
// this is when the user first arrives to this url, display the form
else if ($prg === false) {
return $view;
}
// lets retrieve the post data stored in the PRG session
$post = $prg;
// validate the form
$form->setData($post);
if(!$form->isValid())
return $view;
// if data are valid, then save
// save the brand
$brand = $product->getBrand();
$brandTable = $this->getBrandTable();
$brand = $brandTable->save($brand);
$brandId = $brandTable->getLastInsertValue();
$product->setBrandId($brandId);
// save the categories
$categoryTable = $this->getCategoryTable();
$categoryTable->persist($product->getCategories())->flush();
$categoryIds = implode(",", $categoryTable->getEntityIds());
$product->setCategoryIds($categoryIds);
// save the product
$productTable = $this->getProductTable();
$product = $productTable->save($product);
$this->redirect()->toRoute('product');
return $view;
}
public function editAction ()
{
$form = new CreateProduct();
$product = $this->getServiceLocator()->get('Product\Entity\Product');
$form->bind($product);
// action viewscript
$view = new ViewModel(array(
'form' => $form
));
$productTable = $this->getProductTable();
if ($id = $this->params('id')) {
$product = $this->getProductTable()->getByProductId($id);
// get the brands
$brand = $this->getBrandTable()->getByBrandId($product->getBrandId());
$product->setBrand($brand);
// get the categories
$categoryIds = explode(",", $product->getCategoryIds());
$categories = $this->getCategoryTable()->getAllByCategoryId($categoryIds);
$product->setCategories($categories);
$form->bind($product);
}
// do Post/Redirect/Get (PRG) strategy to stop user refresh/back button
$prg = $this->prg($this->getRequest()->getRequestUri(), true);
if ($prg instanceof Response) {
return $prg;
}
// this is when the user first arrives to this url, display the form
else if ($prg === false) {
return $view;
}
// lets retrieve the post data stored in the PRG session
$post = $prg;
// validate the form
$form->setData($post);
if(!$form->isValid())
return $view;
\Zend\Debug\Debug::dump(__METHOD__.' '.__LINE__);
\Zend\Debug\Debug::dump($post);
\Zend\Debug\Debug::dump($product);
return $view;
}
/**
*
* #return \Product\Table\ProductTable
*/
public function getProductTable ()
{
$sm = $this->getServiceLocator();
$table = $sm->get('Product\Table\ProductTable');
return $table;
}
/**
*
* #return \Product\Table\BrandTable
*/
public function getBrandTable ()
{
return $this->getServiceLocator()
->get('Product\Table\BrandTable');
}
/**
*
* #return \Product\Table\CategoryTable
*/
public function getCategoryTable ()
{
return $this->getServiceLocator()
->get('Product\Table\CategoryTable');
}
}
What i want to do is next:
Create simple form with FormBuilder
When form is submitted the result to be saved into database for particular user ( based on its ID )
In addition is the code from the controller:
public function helloAction(Request $request, $id){//displaying individual results for particular user//
// find the username which was in the view//
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT b FROM AcmeWebBundle:baza b WHERE b.id = :id' )
->setParameter('id',$id);
$total = $query->getResult();
$baza = new baza ();
$em = $this->getDoctrine()->getManager();
$em->persist($baza);
$form = $this->createFormBuilder($baza)
->add ('rating','choice',array('label'=>'TEST44','choices'=>array(
'1'=>'1',
'2'=>'2',
'3'=>'3',
'4'=>'4'
),
'expanded'=>true,
'multiple'=>false
))
->getForm();
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database
$em->flush();
return new Response('<h1>THANKS FOR Your feedback !!!!</h1>');
}
}
return $this->render('AcmeWebBundle:Default:hello.html.twig',array('all'=>$total,'id'=>$id ,'form'=>$form->createView()));
}
}
But this creates new row in the database, and add value only for the rating column.Moreover, id field,username and etc.. are empty.
What i want to do is, rating to be added for the colum rating, but for specific ID.
In the following example I create a form, get the data on POST and then persist the fresh object or a modified one, there is no point in persisting an empty object.
public function historialAction(Request $request)
{
$form = $this->createFormBuilder()
->add('phone', 'text', array('attr' => array('autofocus' => '')))
->add('period', 'number', array('attr' => array('value' => '12')))
->getForm();
if ($request->isMethod('POST')) {
$form->bind($request);
// data is an array with "phone" and "period" keys
$data = $form->getData();
$em = $this->getDoctrine()->getManager();
$contract = $em->getRepository('FrontBundle:Contract')->getContractByPhone($data["phone"]);
$contract->setOwner("John Doe");
$contract->setPhone($data["phone"]);
// or this could be $contract = new Contract("John Doe", $data["phone"], $data["period"]);
$em->persist($contract); // I set/modify the properties then persist
}
You could set the rating to the user entity like so..
if ($form->isValid())
$rating = $form->get('rating')->getData();
$user->setRating($rating);
// Assuming $user is the user entity
// etc..
I'm using symfony2 and createForm to get the http post data. After witch I do:
$Data = (array) $form->getData();
And I get:
array (size=1)
'�Far\MT\AccountBundle\Entity\Movement�toAccount' => int 3
I don't think this is the normal behavior for these cases, any sugestions?
the toAccount should be the complete index name.
Wasn't able to reproduce the conditions in a test case for the cli:
<?php
namespace A;
class MyClass
{
public $id;
public $name;
public $age;
}
$object = new MyClass();
$object->name = "Andre";
$object->id = 1;
$object->age = 30;
var_dump($object);
$Ar = (array) $object;
var_dump($Ar)
This above worked ok.
I used this solution:
//comment
$Data = $form->getData();
$obj = new \ReflectionObject($Data);
$props = $obj->getProperties();
$propname = array();
foreach ($props as $prop) {
$tmp = "get".ucfirst($prop->name);
if (($res = $Data->$tmp() )!== null) {
$propname[$prop->name] = $res;
}
}
$tmpSearch = $propname;
I'll clean it up after.
You can use the Symfony normalizer class, as your propose will fail when you have fields in your form name with underscore like 'facility_id' but your setter is called facilityId
<?php
$data = $form->getData();
$normalizers = new \Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer();
$norm = $normalizers->normalize($data);
print_r($norm);
you'll get output like
Array ( [fullname] => fullnameVal [email] => emaile#lkjl.com [phoneNumber] => 5554444 [facilityId] => 123132 )