Symfony form->bind fails - php

I'm working with a few custom forms, and one of them isn't binding it's values on a POST. I'm using the same logic for each, and only one of them isn't working. Here's the code:
public function executeMediaFileUpload(sfWebRequest $request) {
$this->form = new MediaFileUploadForm();
if (!$request->isMethod('POST'))
$psk = $request->getParameter('psk');
else {
$this->form->bind($request->getParameter($this->form->getName()), $request->getFiles($this->form->getName()));
$this->logMessage('VALUE: ' . $this->form->getValue('version'));
$psk = $this->form->getValue('application');
}
$this->logMessage('PSK: ' . $psk);
$app = Doctrine::getTable('Application')->find(array($psk));
$this->form->setDefault('application', $app->getPsk());
$this->form->setDefault('version', $app->getVersion()->getLast()->getPsk());
On the initial GET, I can see the value passed in via psk getting set as the default for application in the generated HTML, and all the values show up in the POST request in Firebug, but after I bind the form, it still contains no values.
EDIT:
Yes, the form is setup as multipart and POST. And I'm calling $this->widgetSchema->setNameFormat('values[%s]') in the form.
EDIT2: Here's the HTML for the form, and getName returns "values":
<form name="mediafiles" action="<?php echo url_for('application/mediaFileUpload') ?>" method="POST" <?php $form->isMultipart() and print 'enctype="multipart/form-data" ' ?> id="applications">
<div class="clear">
<div>
<?php echo $form->renderHiddenFields() ?>
<?php foreach($form as $widget): ?>
<?php if (!$widget->isHidden()): ?>
<?php echo $widget->renderLabel() ?>
<?php echo $widget->renderError() ?>
<?php echo $widget->render() ?>
<?php endif ?>
<?php endforeach ?>
</div>
</div>
<!-- Start Bottom Sub Navigation -->
<div class="subnav clear">
Cancel
Upload
</div>
<!-- End Bottom Sub Navigation -->

Check in the code generated on your browser (or firebug) for the form. Form values use to have a name, according to your "name format" configuration, like this:
<input type="text" name="my_name_format[widget_name]" />
So in order to access its value passed to action you must use something like this:
$parameters = $request->getParameter('my_name_format');
$parameter = $parameters['widget_name'];
And like this for each value of your form using "parameters" array.
An simple draft implementing my solution into your code looks like this:
public function executeMediaFileUpload(sfWebRequest $request) {
$this->form = new MediaFileUploadForm();
$parameters = $request->getParameter('values'); // Since you used $this->widgetSchema->setNameFormat('values[%s]')
if (!$request->isMethod('POST'))
$psk = $parameters['psk'];
else {
$this->form->bind($request->getParameter($this->form->getName()), $request->getFiles($this->form->getName()));
$this->logMessage('VALUE: ' . $parameters['version']);
$psk = $parameters['application'];
}
$this->logMessage('PSK: ' . $psk);
$app = Doctrine::getTable('Application')->find(array($psk));
$this->form->setDefault('application', $app->getPsk());
$this->form->setDefault('version', $app->getVersion()->getLast()->getPsk());
Hope this solution works.

Related

PHP CodeIgniter: Updating a dynamic array bound to an input field

What I'm about to show might be the most horrific code in existence, so be prepared. I'm new to PHP and received a CodeIgniter project. Here we go:
In my edit_article view, I dynamically generate <input> fields and make them accessible to the controller by posting them as an array, notice name="pricelevel_checked_array[]":
<form id="form-work" class="form-horizontal" role="form" autocomplete="off" method="post">
<!-- excluded code to display form content -->
<?php
$pricelevel_array = array();
$count = 0; ?>
<?php foreach($array_used_for_loop as $item_used_for_loop): ?>
<?php $article_group_price = ""; ?>
<!-- excluded code to fill $article_group_price -->
<div class="col-sm-2">
<div class="checkbox">
<span class="bg-transparent left">
<input type="checkbox" data-init-plugin="switchery" data-size="small" data-color="primary" id="<?=$count?>"
<?php if($article_group_price !== ""): ?>
<?php array_push($pricelevel_array, 1); ?>
checked="checked"
<?php else: array_push($pricelevel_array, 0); ?>
<?php endif; ?>
onchange="groupprice_active_changed(this)"/>
</span>
</div>
</div>
<input hidden type="number" id="pricelevel_checked_array" name="pricelevel_checked_array[]" value="<?=$pricelevel_array[$count];?>">
<?php $count++; ?>
<?php endforeach; ?>
</form>
As you can see, I fill that array with 1's or 0's depending on the value of $article_group_price (I get these values from the controller and originally the database).
It all works fine upon first loading the view and the array is filled correctly, but I can't seem to update the array when I check- or uncheck a checkbox.
I've tried to do this quick and dirty using javascript onchange="groupprice_active_changed(this)" where I would use the $count variable to change the index of the array, but unfortunatly that didn't work out since I only get one value and not the entire array:
<script>
function groupprice_active_changed(obj) {
if($(obj).is(":checked")){
alert("Yes checked");
var input_value_array = document.getElementById('pricelevel_checked_array').value;
console.log(input_value_array);
for (index = 0; index < input_value_array.length; index++) {
console.log(input_value_array[index]);
}
}else{
alert("not checked")
}
}
</script>
How can I best update this array or change my code so I can post the dynamic generated checkboxes to the controller? Another problem is that I need the checkbox-id in the controller, even if it's false. And that the browser doesn't post an unchecked checkbox value. So, just passing the checkboxes isn't an option.
I'm of course prepared to post more code.
Thank you
Disclaimer: Please no steal
View: Complete code
Controller: Complete code
Edit 1: Changed 'php' to 'the browser' in the last section
Edit 2: Added as good as the whole code because filtering out will only make it more difficult.
One technique I have see used to make checkboxes behave better is to use
a hidden input with the same name as the checkbox. Put the hidden input before
the checkbox. If the checkbox is not checked, the value of the hidden input
gets sent. If you check the checkbox then the checkbox value overrides the hidden input.
This works because only one of the values is sent. The browser sends the later one.
Take a look at the following example.
<html>
<head>
</head>
<body>
<div>
<form method="post">
<input type="hidden" name="foo" value="off">
<input type="checkbox" name="foo" /> Foo
<input type="submit" />
</form>
</div>
</body>
</html>
<?php if ( ! empty($_POST) ) : ?>
<div> Hello </div>
<div>
Checkbox is <?= $_POST['foo']?>
</div>
<?php endif ?>
I eventually made the decision to drop the whole array approach and follow the KISS principle by passing my index to the controller. I use these indexes to only save the rows that are checked. Thanks to #ryantxr for showing me that I was overthinking all this.
v_edit_article
<?php $index = 0; ?>
<?php foreach($array_used_for_loop as $item_used_for_loop): ?>
<?php $article_group_price = ""; ?>
<!-- excluded code to fill $article_group_price -->
<div class="col-sm-2">
<div class="checkbox">
<span class="bg-transparent left">
<input type="checkbox" name="group_active[]" data-init-plugin="switchery" data-size="small" data-color="primary" value="<?=$index;?>"
<?php if($article_group_price !== ""): ?>
checked="checked"
<?php endif; ?>/>
</span>
</div>
</div>
</div>
<?php $index++; ?>
<?php endforeach; ?>
admin (controller)
public function edit_article($id) {
// Excluded code
$group_prices_active = array();
if(isset($data['group_active'])):
echo "<script>console.log('GROUP_ACTIVE ".print_r($data['pricelevel_checked'])."');</script>";
foreach($data['group_active'] as $value):
array_push($group_prices_active, $group_prices[$value]);
endforeach;
echo "<script>console.log('GROUP_PRICES_ACTIVE ".print_r($group_price_active)."');</script>";
unset($data['group_active']);
endif;
// Excluded code
$this->m_articles->edit_article($data, $id, $article_types, $group_prices_active);
$this->session->set_flashdata('succes', $this->lang->line('edit_success'));
redirect('/administrator/articles', 'refresh');
}

PHP separate id for every div

to be honest this is more of a how to then help with code i already have. So i hope this is okay, else of course i will delete my question again. Anyway here goes i have a site with boxes, with a picture headline and a submit button. All the info in these boxes is being delivered, from my database. And of course in my database i also have a id cell, and if i try to echo out the id cell with the rest of the info in the box it shows up fine. But when i try to assign the id output variable to a header location, i do for some weird reason always get the id 3. Eventhough the id´s shows up perfectly fine, in the boxes. I have included my php code and i am still a beginner to php so sorry for this noob question. :)
session_start();
include 'connection.php';
$sqlSelect = mysqli_query($con,"SELECT * FROM inspi");
while ($feed=mysqli_fetch_array($sqlSelect))
{
$id = $feed['id'];
if(isset($_POST['readArticle']))
{
$id = $_SESSION['id'];
header("Location:"."redirect.php?".SID.$idArticle);
}
?>
<div class="contentBoxOne">
<img width="100%" height="170px" src="userpics/<?php echo $feed['image']; ?>">
<div class="line"></div>
<form method="post" action="">
<input type="submit" name="readArticle" class="readArticle" value="Læs nu!">
</form>
<?php $idArticle= $feed['id'];?>
<h2><?php echo $feed['headline'];?></h2>
</div>
You are setting $idArticle at the bottom of the loop but trying to use it at the top so it will be pulling it from the previous result. Try:
while ($feed=mysqli_fetch_assoc($sqlSelect)){
$idArticle= $feed['id'];
$sid = $_SESSION['id'];
if(isset($_POST['readArticle']))
{
header("Location:"."redirect.php?".$sid.$idArticle);
}
//rest of code
}
You will have to put div inside the loop.
I also replaced the header redirect with form action attribute (you may want to replace method POST with GET instead).
ID is passed with a hidden field
<?php
include 'connection.php';
$sqlSelect = mysqli_query($con,"SELECT * FROM inspi");
while ($feed=mysqli_fetch_assoc($sqlSelect))
{
$id = (int)$feed['id'];
?>
<div class="contentBoxOne">
<img width="100%" height="170px" src="userpics/<?php echo $feed['image']; ?>">
<div class="line"></div>
<form method="post" action="redirect.php">
<input type="hidden" name="id" value="<?php echo $id; ?>">
<input type="submit" name="readArticle" class="readArticle" value="Læs nu!">
</form>
<h2><?php echo $feed['headline']; ?></h2>
debug: <pre><?php print_r($feed); ?></pre>
</div>
<?php } // end of while loop ?>

Phalcon does change views

<?php
class IndexController extends \Phalcon\Mvc\Controller {
public function indexAction(){
}
}
?>
<?php
class SignupController extends \Phalcon\Mvc\Controller {
public function indexAction(){
}
}
?>
<?php
echo "<h1>Hello!</h1>";
echo Phalcon\Tag::linkTo( "signup", "Sign Up Here!");
?>
<?php use Phalcon\Tag; ?>
<h2>Sign up using this form</h2>
<?php echo Tag::form( "signup/register" ); ?>
<p>
<label for="name">Name</label>
<?php echo Tag::textfield( "name" ); ?>
</p>
<p>
<label for="email">E-Mail</label>
<?php Tag::textfield( "email" ); ?>
</p>
<p>
<?php echo Tag::submitButton( "Register" ); ?>
</p>
</form>
I was following a tutorial on phalcon framework here but it can't get it to work. I have created the controllers for the index page and the signup page. I also created the views for the index controller and the view for the signup controller.
What happens is that when I click on the link to go to the signup page it shows the url correct which means we should be on the signup page but it shows the index view not the signup view. Basically when i click on the signup link the only thing that changes in the browser is the url but not the page.
anyone know what is going on here?
Ok,
I got this working in the end.
Make sure that (in my case Nginx) you confirm that it has been set up correctly.
The second thing to look at is the code to handle the request. I have used this:
$application = new \Phalcon\Mvc\Application();
$application->setDI($di);
if (!empty($_SERVER['REQUEST_URI'])) {
$pathInfo = $_SERVER['REQUEST_URI'];
} else {
$pathInfo = '/';
}
echo $application->handle($pathInfo)->getContent();
This isn't exactly what I wanted, but for some reason my PATH_INFO was coming out as empty, even when I have set cgi.fix_pathinfo to 1 in the php.ini
Hope this helps.

POST Data is not sent

I'm having some weird issues with this code block, it's a little school project, going well so far but the form at the bottom is not returning any post data. the var_dump($_POST); never shows any post data being submitted from this particular form.
I just cannot understand why, been struggling with it for so long.
Here's the code, i couldn't understand to format it on this page, adding 4 indents for every line seemed a bit tedious.
<?php session_start();
require_once'user.class.php';
require_once 'posts.class.php';
require_once'comments.class.php';
$posts = new Posts($user->getID(), $db);
$comment = new Comments($user->getID(), $db);
include_once'includes/header.php';
include_once'includes/nav.php';
?>
<h2><br></h2>
<?php
include_once'includes/intro.php';
// CONTENT
$post = $posts->showPost($_GET['id']);
$title = $post['title'];
$content = $post['content'];
$created = $post['timestamp'];
echo "<section> <article class='blogPost'> <header> " . " <h2>$title</h2> " . "<p> Posted on $created <a href ='#comments'> X comments</a></p></header>" . "<p>$content</p>" . "</article> </section>";
var_dump($_POST);
if (isset($_POST['submit_comment']) && isset($_POST['id_comment'])) {
echo "Kom seg inn i ifen";
$pid = $_GET['id'];
$comment->newComment ($db, $user->getID(), $pid, $_POST['id_comment']);
header ("location: showPost.php?id=$pid");
exit ();
}
?>
<form name='commentform' action='showPost.php?id=<?php echo $_GET['id'];?>' method='POST'>
<h3>Post a comment</h3>
<p>
<label for='id_comment'>Comment</label>
<textarea name='id_comment' id='id_comment' required></textarea>
</p>
<p><input style='width: 100%;' type='submit' name='submit_comment' value='Legg til kommentar' /></p>
</form>
<?php
include_once'includes/asidefooter.php';
?>
Thanks for all help!
It looks like if post is data present, the user is redirected. You will only see the post data at the time the form is submitted, and the redirect will cause another page load and the data won't be present anymore.
Can you see the post data if you comment out the redirect, with:
//header ("location: showPost.php?id=$pid");
//exit ();
Something is causing a redirect, which is turning the request into a GET. If you're trying to submit to a index.php then don't forget the ending slash.

How to save updated CKEditor content to database?

I've searched high and low both on Google and this site for an answer to this question with no luck.
I'm working on a custom CMS for future customers who want to do their own maintenance. Here's the code that loads the current page content into the textarea from the database:
if(isset($_GET['id'])) {
$id = $_GET['id'];
$content = mysql_query("SELECT title, content FROM pages WHERE id=".$id);
$search = mysql_num_rows($content);
if($search > 0){
while($page = mysql_fetch_array($content)) { ?>
<h1>Editing <?php echo $page['title']; ?></h1>
<form id="editform" action="save.php?id=<?php echo $_GET['id']; ?>" method="post">
<textarea id="editor" name="content"><?php echo $page['content']; ?></textarea>
</form>
<?php }
}
} ?>
Here's the code in save.php:
<?php
if(isset($_POST['content'])){
$content = $_POST['content'];
$id = $_GET['id'];
echo $content;
mysql_query("UPDATE pages SET content=".$content." WHERE id=".$id);
}
?>
The problem is that the POST['content'] keeps getting the original content, not the edited one that the user just submitted.
How do I fix this?
The data should be passed automatically when the form is posted. Here is the "Integration" page page from the Developers Guide that explains this:
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Integration
Are you sure that the query is being run successfully and that the content field is being updated? I ask because the code you posted says that in save.php, you are using:
$id = $_GET['id'];
This would seem to cause a problem, because you are using method="post" in your form, not method="get".
Could you also post the code you are using to replace the textarea with CKEditor. Are you using the PHP method:
<?php
$CKEditor = new CKEditor();
$CKEditor->basePath = '/ckeditor/';
$CKEditor->replace("content");
?>
Or the JavaScript method:
<script language="Javascript">
<!--
CKEDITOR.replace( 'content' );
//-->
</script>
Be Well,
Joe
Follow up to question in comments
Hi Purmou,
I didn't notice that you were including the id in the form action, sorry about that. If you did want to use it as a $_POST variable instead, you could include it as a hidden field like this:
<form id="editform" action="save.php?id=<?php echo $_GET['id']; ?>" method="post">
<input type="hidden" id="id" name="id" value="<?php echo $_GET['id']; ?>" />
<textarea id="editor" name="content"><?php echo $page['content']; ?></textarea>
There is some good documentaion about loading the editor via PHP in the _samples folder of the CKEditor install:
http://YourSite.com/ckeditor/_samples/php/
http://YourSite.com/ckeditor/_samples/php/replace.php, has the basic settings:
<?php
// Include the CKEditor class.
include_once "ckeditor/ckeditor.php";
// Create a class instance.
$CKEditor = new CKEditor();
// Path to the CKEditor directory.
$CKEditor->basePath = '/ckeditor/';
// Replace a textarea element with an id (or name) of "textarea_id".
$CKEditor->replace("textarea_id");
?>
Similar to the JavaScript method, you can add config options before you replace the textarea. An example from the "advanced.php" file:
$CKEditor->config['width'] = 600;
To use the PHP method with your specific code, do this:
if(isset($_GET['id'])) {
$id = $_GET['id'];
$content = mysql_query("SELECT title, content FROM pages WHERE id=".$id);
$search = mysql_num_rows($content);
if($search > 0){
while($page = mysql_fetch_array($content)) { ?>
<h1>Editing <?php echo $page['title']; ?></h1>
<form id="editform" action="save.php?id=<?php echo $_GET['id']; ?>" method="post">
<textarea id="content" name="content"><?php echo $page['content']; ?></textarea>
</form>
<?php }
include_once "ckeditor/ckeditor.php";
$CKEditor = new CKEditor();
$CKEditor->basePath = '/ckeditor/';
$CKEditor->replace("content");
}
} ?>
I changed the textarea id from "editor" to "content". I would recommend against using "editor" for the id or name, because it's used in the CKEditor code to refer to the CKEditor instance.
You can do config settings in the page where you load the editor or in the config.js file or in your own custom config file.
I spent some time trying to catch the value of the form content field after the form is submitted, but was only able to see it before CKEditor had updated the contents.
Be Well,
Joe

Categories