Symfony 1.4 forms using Propel Object '<class here>' not Found - php

From this page:
main_dev.php/player/new
to (when I click submit):
main_dev.php/player/edit/player_id/(no id)
if I put an id here it displays fine.
When I click the submit button (somehow it saves) but displays this:
404 | Not Found | sfError404Exception
Object Player does not exist().
this is my baseform:
$this->setWidgets(array(
'player_id' => new sfWidgetFormInputHidden(), //primary key auto increment()
'player_name' => new sfWidgetFormInputText(),
'player_gold' => new sfWidgetFormInputText(),
'chara_id' => new sfWidgetFormInputText(),
'open_social_id' => new sfWidgetFormInputText(),
));
im suspecting that the issue here is that player_id is not displayed and is auto increment. that means that when i submit the form player_id is left blank and since symfony cannot find where to get the id for the reference to display a record it goes 404, is there any workaround in this?
and my action.class is left from the default(instance when i generated it) so i think is not an issue
heres what the code for saving the form:
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$Player = $form->save();
$this->redirect('player/edit?player_id='.$Player->getPlayerId());
}
}
and ofcourse for the new page controller:
public function executeNew(sfWebRequest $request)
{
$this->form = new PlayerForm();
}

If the POST request saves a new Player object (in the database), it is not your BasePlayerForm.class, nor the submit url.
If your routing works when manually entered, and not when called within the action class, then your routing.yml is probably not the problem.
If you have not over-written the configure() of the BasePlayerForm.class.php (in PlayerForm.class.php, or anywhere else), then it is not in your lib/form/ classes.
Either this answer is useless (sorry) or you do not actually mean that the action "saves" the object to the database - in which case, check the submit url/request from the newSuccess template; also verify your routing:
Your newSuccess.php form tag action should POST to main_dev.php/player:
<form method="post" action="/main_dev.php/player">
[And pass the id rendered in html as <input type="hidden" name="player[player_id]" id="player_id" />.]
Lastly, the edit routing in the url will normally match player/:player_id/edit - check if you actually have an auto-created "id" column in your schema/database in addition to the "player_id" which might really be what is causing this.

Related

Different Variables/Functions for one twig.html

Since 3 weeks i try to learn php with the symfony framework.
I want to build an application with which i can track my expanses.
I made good progress but since 2 days i have a little logic problem so maybe someone can help me here.
I want to make a dashboard.(the main side of the project) There the user can monitor the expenditures.
This works. Now i want also a form at the dashboard, so the user can add new expenditures. I already implement a form but with a extra route. So in my ExpenditureController i have the functions dashboard and the function addExpenditure which generate different twig.html templates.
So the user can monitor his expenditures with ...budgetapp/expenditure/dashboard
and he can add new Expenditure with ...budgetapp/expenditure/addexpenditure
My Dashboard-Function
#[Route('/dashboard/', name: 'dashboard')]
public function dashboard(ExpenditureRepository $ar)
{
$user = $this->getUser();
$expenditures = $ar-> findexpendituresOfUser($user);
return $this->render('expenditure/dashboard.html.twig', [
'expenditures' => $expenditures,
]);
}
The expenditure/dashboard.html.twig shows the Expentiures of the current user in a table
My addExpenditure-Function
public function addExpenditure (ManagerRegistry $doctrine, Request $request){
$em = $doctrine->getManager();
$expenditure = new Expenditure();
$form = $this->createForm(ExpenditureType::class, $Expenditure);
$form->handleRequest($request);
if($form->isSubmitted()){
$em->persist($expenditure);
$em->flush();
}
return $this->render('expenditure/addexpenditure.html.twig', [
'addexpenditureForm' => $form->createView()
]);
}
The expenditure/addexpenditure.html.twig looks like this:
{% block body %}
<div class="container">
{{form(eintragenForm)}}
</div>
{% endblock %}
My problem /mistake in thinking:
How can i implement the form to the dashboard? So of course i can take the code from the addexpenditure function and put it 1:1 in the dashboard-funciton. but i dont think this is the right way? I also tried to including template fragments with the offical Embedding Controllers Documentation of Symfony, but this also dont work.
So someone can help me with a suggestion how you would handle this in your project?
Best regards
Markus
There are two possible solutions: put both view and add logic inside one controller's action, or separate them. Since you probably have some validation, it's reasonable to have both add and view code inside one action (otherwise, you'll have to pass errors via sessions, which is not very pretty). So basically, your dashboard/add action will look like this:
#[Route('/dashboard/', name: 'dashboard')]
public function dashboard(Request $request, ExpenditureRepository $ar, ManagerRegistry $doctrine)
{
$expenditure = new Expenditure();
$form = $this->createForm(ExpenditureType::class, $expenditure);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $doctrine->getManager();
$em->persist($expenditure);
$em->flush();
return $this->redirectToRoute('dashboard');
}
}
$user = $this->getUser();
$expenditures = $ar-> findexpendituresOfUser($user);
return $this->render(
'expenditure/dashboard.html.twig',
[
'expenditures' => $expenditures,
'addexpenditureForm' => $form->createView(),
]
);
}
What's happening here:
First you check if POST http method was used, if it was - it means
that form has been submitted and you can handle it. There is an alternative solution without checking request method, see comments for more.
If this is a GET request, just show ordinary dashboard
If the form is submitted and it's valid - save data and redirect to
the same page. Otherwise, you'll need to empty all submitted data
from the form, etc. (it's not the right way to do it)
If the form is invalid, do not redirect, just render the page
normally, and all errors will be shown.
Finally, you of course have to render the form on your dashboard.html.twig like you did: {{form(eintragenForm)}}

Validate field in form - check if "product" exists in CakePhp 3

I've got problem with field validation.
I would like to validate form through model. I want to check if field with some value exists.
I would like to block using some titles more than once.
For example
if field "Site" with title "Main" exists in database, you can't validate form.
If it doesn't exist, you can pass it.
I would like to allow user to add just one "Site" with title "Main", but he can add "Site" with any other title in any case.
Have you got some idea how to solve it?
I think you have two options.
(1) Setup an Ajax request to the server.
To do so:
Create a function, that responds to an Ajax request, in your SiteController named checkName()
public function checkName($name) {
// allow ajax requests
$this->request->allowMethod(['ajax']);
// perform your check within the db
$isExistent = [...];
// prepare the response
$response = ['name' => $name, 'isExistent' => $isExistent];
if ($this->request->isAjax()){
$this->autoRender = false;
$this->response->disableCache();
$this->response->type(['json' => 'application/json']);
$this->response->body(json_encode($response));
}
}
Add the route to your routes file with the option '_ext' => 'json'
Prepare your Javascript Ajax function that call the route you have defined and attach it on the onchange attribute of your input field. (see this link for a simple example: http://www.w3schools.com/jquery/ajax_ajax.asp)
(2) Make the 'name' field of the Site table unique.
To do so you could add the following function to your SiteTable class
public function buildRules(
RulesChecker $rules
) {
$rules->add($rules->isUnique(['name']));
return $rules;
}

Why does CakePHP add New Rows when 'post' is replaced by 'get'?

I edit a row on the Post table or add a new row to it from edit() function in PostsController. The function looks like this:
public function edit($id = null) {
// Has any form data been POSTed?
if ($this->request->is('post')) { //Replaced 'post' by 'get' in this line
// If the form data can be validated and saved...
if ($this->Post->save($this->request->data)) {
// Set a session flash message and redirect.
$this->Session->setFlash('Updated the Post!');
return $this->redirect('/posts');
}
}
// If no form data, find the post to be edited
// and hand it to the view.
$this->set('post', $this->Post->findById($id));
}
I simply replaced 'post' by 'get' to see what would happen and it went on creating new rows without even taking me to the form. I still get the flash message 'Updated the Post!', but without taking any form data.
If the code in edit.ctp is required, here it is:
<?php
echo $this->Form->Create('Post');
echo $this->Form->input('id', array('type' => 'hidden','default'=>$post['Post' ['id']));
echo $this->Form->input('title',array('default'=>$post['Post']['title']));
echo $this->Form->input('body',array('default'=>$post['Post']['body']));
echo $this->Form->end('Update');
?>
Any thoughts on why this might be happening?
Edit: Added CakePHP Version
I am using CakePHP 2.4.5
What you are doing makes no sense.
Why would you want to switch the "post" by "get" here?
Of course it will then generate new rows, as you effectively trigger a save on each page load (GET).
Don't do that.
The code you had there was just fine - IF you also took PUT into consideration.
For edit forms, it is not a post, but:
if ($this->request->is('put')) {}
PS: If you want to make sure it always works for both add/edit, use
if ($this->request->is(array('post', 'put')) {}
But NEVER replace it with "get".

Symfony2 Saving data of related Entity after submiting form

I'm starting developing with Symfony2 and looks like I need help. I have Product entity related with SynchronizationSetting entity. I can edit product data by form maped with his entity. But I also need to modify some data related to product in SynchronizationSetting. To do that I've modified the form so it look like that (Vendor\ProductBundle\Form\ProductType.php):
...
->add('synchronization_setting', 'choice', array(
'choices' => array('daily' => 'Daily', 'weekly' => 'Weekly', 'never' => 'Never'))
After form is submitted selected checkbox values are passed to setSynchronizationSetting method in Product Entity. Then I do that (Vendor\ProductBundle\Entity\SynchronizationSetting.php):
public function setSynchronizationSetting($data)
{
$synchronizationSetting = new SynchronizationSetting();
$synchronizationSetting->setDaily(in_array('daily', $data) ? '1' : '0');
...
}
And now I need to somehow save those SynchronizationSetting entity into database. I read that calling entity manager from here is very bad practice so... how should I save this?
One possible way (I'm not sure if it's good practice)
public function setSynchronizationSetting($data)
{
$synchronizationSetting = new SynchronizationSetting();
$synchronizationSetting->setDaily(in_array('daily', $data) ? '1' : '0');
}
public function retSynchronizationSetting()
{
return $this->synchronizationSetting;
}
Then in your controller in place where you handle form data you call retSynchronizationSetting() and save entity using EntityManager.

Dynamic form fields in Symfony 1.4

I'm working on an e-commerce project and I got stuck at the cart update. Here I have to present a form using the contents of the current cart, with input fields containing the current quantities.
I checked the documentation and the forums, but I didn't find anything useful. The problem is that i cannot declare the exact form fields in my form class because I don't know how many fields will be there. I tried this:
class CartForm extends sfForm {
public function configure()
{
$cart = sfContext::getInstance()->getUser()->getShoppingCart();
foreach ($cart->getItems() as $item) {
$widgetName = $item->getId().'_quantity';
$this->widgetSchema[$widgetName] = new sfWidgetFormInput(
array(),
array(
'class' => 'quantity-input',
'id' => null,
'name' => $widgetName
)
);
$this->widgetSchema->setDefault($widgetName, $item->getQuantity());
$this->validatorSchema[$widgetName] = new sfValidatorInteger(array(
'required' => true,
'min' => 1
),
array());
}
unset($cart);
$this->getWidgetSchema()->getFormFormatter()->setRowFormat('%field%%error%%hidden_fields%');
}
}
but I got some errors:
Fatal error: Cannot use object of type sfShoppingCart as array in /home/sfprojects/mdmall/lib/vendor/symfony/lib/form/sfForm.class.php on line 784
so this is not the right way. I tried to use raw fields without any form classes (and validators) but something very odd happens, instead of getting the $_POST values i get a 404 error because when I submit the form it doesn't trigger this:
cart_update:
url: /cart/update.:sf_format
class: sfRequestRoute
param: { module: cart, action: update, sf_format: html }
requirements: { sf_method: post }
If I remove the requirement, cart/update runs, but I dont have the $_POST data in the request object. Do you have any ideas?
These will help you with regard to dynamically adding form fields and working with validation of those fields:
Dynamic Emedded forms (but the process is similar for fields)
Dynamic Form Fields
Custom Validation

Categories