How to save a binary directly to a database table field (JSON data) in Yii? - forms

I'm working on a Yii project with a database, containing a table, where almost all it's data is saved in a field as JSON (it's crazy, but it is so as it is):
id INTEGER
user_id INTEGER
data LONGTEXT
This "JSON field" data has following structure and contains inter alia an image:
{
"id":"1",
"foo":"bar",
...
"bat":{
"baz":"buz",
"name":"Joe Doe",
"my_picture":"iVBORw0KGgoAAAANSUhEUgAAAGQA...", <-- binary
...
}
}
Displaying it is no problem, but now I want to make the data ediable. My form looks like this:
<?php
$form=$this->beginWidget('CActiveForm', array(
'id' => 'insurance-form',
'htmlOptions' => array('enctype' => 'multipart/form-data'),
'enableAjaxValidation'=>false,
));
?>
<div class="row">
<?php echo $form->labelEx($model, 'provider_name'); ?>
<?php
echo $form->textField($model, 'data[provider][name]', array(
'size'=>60, 'maxlength'=>255, "autocomplete"=>"off"
));
?>
<?php echo $form->error($model, 'data[provider][name]'); ?>
</div>
It works.
I know, that for image upload I need fileField(...), but cannot find out, how to configure it in order to save the image directly to the database. How to do his?

view
<div class="row">
<?php echo $form->labelEx($model, 'provider_name'); ?>
<?php
echo $form->fileField($model, 'data[provider][name]', array());
?>
<?php echo $form->error($model, 'data[provider][name]'); ?>
</div>
controller
public function actionUpdate($id)
{
$model = $this->loadModel($id);
if(isset($_POST['External'])) {
$modelDataArray = $model->data;
// adding the image as string to the POSted data
if (isset($_FILES['MyModel']['name']['data']['provider']['picture'])) {
$_POST['MyModel']['data']['provider']['picture'] = base64_encode(
file_get_contents($_FILES['MyModel']['tmp_name']['data']['provider']['picture'])
);
}
$inputFieldData = $_POST['MyModel']['data'];
$updatedDataArray = array_replace_recursive($modelDataArray, $inputFieldData);
$model->attributes = $_POST['MyModel'];
$updatedDataJson = json_encode($updatedDataArray);
$model->setAttribute('data', $updatedDataJson);
if($model->save()) {
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('update', array(
'model' => $model,
));
}
CActiveRecord model
no special changes

Related

Troubleshooting CakePHP form submission

I recently set up the ability to tag posts on my site. I had everything working fine. Then as I was wrapping up I tested all my admin side forms again. The Add Tag form no longer does anything. It doesn't even flash an error or redirect after submission. The page just reloads at the same URL. The only changes to the site I have made since initial testing was move the forms to the admin side of the dev site. Here is some code to hopefully reveal what the mystery is. Also my edit tag form is doing similar thing. It has no flash message but redirects back to the index, like its supposed to but with no changes made to the tag. Ill include the edit code as well.
Add.ctp in src/Template/Admin/Tags/Add.ctp
<div class="tags form large-9 medium-8 columns content">
<?= $this->Form->create($tag) ?>
<div class="form-group">
<fieldset>
<h1 class="page-header">New Tag</h1>
<?php
echo $this->Form->input('name', ['class' => 'form-control']);
?>
</fieldset>
</div>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>
Here is my Add funciton in my TagsController:
public function add()
{
$this->viewBuilder()->layout('admin');
$tag = $this->Tags->newEntity();
if ($this->request->is('post')) {
$tag = $this->Tags->patchEntity($tag, $this->request->data);
if ($this->Tags->save($tag)) {
$this->Flash->success(__('The tag has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The tag could not be saved. Please, try again.'));
}
$this->set(compact('tag'));
$this->set('_serialize', ['tag']);
}
Here is my Edit funciton in my TagsController:
public function edit($id = null)
{
$this->viewBuilder()->layout('admin');
$tag = $this->Tags->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$tag = $this->Tags->patchEntity($tag, $this->request->data);
if ($this->Tags->save($tag)) {
$this->Flash->success(__('The tag has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The tag could not be saved. Please, try again.'));
}
$this->set(compact('tag'));
$this->set('_serialize', ['tag']);
}
Edit.ctp in src/Template/Admin/Tags/Edit.ctp
<div class="tags form large-9 medium-8 columns content">
<?= $this->Form->create($tag) ?>
<div class="form-group">
<fieldset>
<h1 class="page-header">Edit Tag</h1>
<?php
echo $this->Form->input('name', array('class' => 'form-control'));
?>
</fieldset>
</div>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>
Just as a side note. I started getting errors when creating a new post as well.
General error: 1364 Field 'section_id' doesn't have a default value
I did go into my DB and give the field a default value. But then when I fill out the form for a new post again, the error just moves to the next table column. I am assuming they are some how related since they popped up at the same time and because tags and posts are related to each other.
TagsTable:
class TagsTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('tags');
$this->displayField('name');
$this->primaryKey('id');
$this->hasMany('PostsTags', [
'foreignKey' => 'tag_id'
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->requirePresence('name', 'create')
->notEmpty('name');
return $validator;
}
}
Tags Entity:
class Tag extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* #var array
*/
protected $_accessible = [
'*' => false,
'id' => false
];
}
When I place <?php debug($tag); ?> into my add.ctp view this is the out put it gives me:
object(App\Model\Entity\Tag) {
'[new]' => true,
'[accessible]' => [],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Tags'
}
Again, in question always post debug pathEntity output, in your case debug($tag), also Tag Entity, your validation code, and how looks your db tags table.
Answer:
General error: 1364 Field 'section_id' doesn't have a default value
This means that you have not passed a value for this field.
You can change that table field to accept null or empty value and/or set default if not passed from application, or make validation in your TagsTable to be sure if submitted data valid before send to db.
After question updated:
protected $_accessible = [
'*' => false, <---- should be true
'id' => false
];
This means that all fields except id are accessible

Button submit's value not transmitted in POST

I am using Yii2 and I want to create comment functionality on post using Pjax widget.
The comment windows displays all the existing comments for the post adding an edit button to the ones that belongs to the connected user in order to permit changes.
Under this list of comments,there is a form including a textarea and a submit button to allow comment creation.
Each time the user click on an already existing comment 's edit button, a form is displayed to allow update.
How all this actually runs and the trouble I meet:
I can update an existing comment an infinite number of times, and it is what I want.
If, just after refreshing the view post page, I enter a new comment, it
is correctly submitted. But I cannot enter an other one and I want to be able to post more than one. The second time, it appears that the POST contains the content of the comment but nothing
regarding the submit button. Thus I cannot recognize which button has
been clicked.
The same thing happens after I have changed an
existing comment i.e. I cannot create a new comment for the same
reason – nothing about the submit button in the POST.
My question
How comes the submit button is transmitted in the POST only if it is the first one used and it is the first time it is used after a refresh of the page?
Here are the relevant code parts
1-Controller
/**
* display a post
*#param integer $id
*
* return a view
*/
public function actionView ($id){
$post = $this->findModel($id);
$comment=$this->manageComment($post);
return $this->render('view', [
'post_model' => $post,
'comment_model' => $comment,
]);
}
/*
* deals with the post according to the submit value
* if submitted and return the comment under treatment
* otherwise – not submitted – return a new comment
*
*#param $post the post that holds the comments
*
* return a Comment model
*/
protected function manageComment($post)
{
$comment=new Comment;
if(isset($_POST['Comment']) )
{
switch ($_POST['Submit']) {
case 'create':
$comment->attributes=$_POST['Comment'];
if($post->addComment($comment,false))
{
//la création a réussi
if($comment->status==Comment::STATUS_PENDING)
Yii::$app->session->setFlash('success',
Yii::t('app','Thank you for your comment.
Your comment will be visible once it is approved.'));
//on renouvelle le commentaire pour éviter d'avoir
//un bouton update (mise à jour)
return new Comment;
}
break;
case 'update':
$comment=Comment:: find()
->where(['id' => $_POST['Comment']['id']])
->one();
if($comment->attributes=$_POST['Comment']){
if($post->addComment($comment,true))
{
//update successful
if($comment->status==Comment::STATUS_PENDING)
{Yii::$app->session->setFlash('success',
Yii::t('app','Thank you for your comment.
Your comment will be visible once it is approved.'));}
$comment= new Comment;
return $comment;
} else {
//la mise à jour a échoué
$comment= new Comment;
return $comment;
}
}else{echo'load failed'; exit();}
break;
case 'edit':
// echo $_POST['Comment']['id']; exit();
$comment->id = $_POST['Comment']['id'];
return $comment;
break;
default:
}
}
//creation successful
return $comment;
}
2-In Post view
<!--comment_model is passed by PostController-->
<?= $this->render('#app/views/comment/_create-form',
['model' => $comment_model, 'post' => $post_model]); ?>
3 - the _create-form view
<div class="comment-form">
<?php Pjax::begin([ ]);?>
<!-- this bloc must be part of the Pjax in order for the new
comment to appear immediately -->
<div class="comment">
<h4 ><?= Yii::t('app','Comments by users')?></h4>
<div class="comments">
<?php $comments= Comment::find()
->where (['post_id' => $post->id ])
->andWhere(['status' => true])
->all();
foreach($comments as $com){
$identity= User::findIdentity($com->user_id);
$firstname=$identity->firstname;
familyname=$identity->familyname;
$date= Utils::formatTimestamp($com->created_at);
$txt1 = Yii::t('app','Posted by ');
$txt2 = Yii::t('app',' on ');
$text_header =$txt1. $firstname.' '.$familyname.$txt2.$date;
//here we check that $model->id is defined an equal to $com->id
//to include edition form
if (isset($model->id) && ($model->id == $com->id) )//
{
// echo Yii::$app->user->identity->id. ' '.$com->user_id; exit();
echo $this->render(
'_one-comment',(['com' => $com,
'text_header' => $text_header,
'submit_btn' => false,
'with_edit_form' => true]));
} else
{
$submit_btn=false;
if (Yii::$app->user->identity->id == $com->user_id) $submit_btn=true; else $submit_btn=false;
echo $this->render('_one-comment',(['com' => $com, 'text_header' => $text_header, 'submit_btn' => $submit_btn,'with_edit_form' => false]));
}
}?>
</div>
<!--this div should be between Pjax::begin and Pjax::end otheswise it is not refreshed-->
<div id="system-messages" >
<?php foreach (Yii::$app->session->getAllFlashes() as $type => $message): ?>
<?php if (in_array($type, ['failure','success', 'danger', 'warning', 'info'])): ?>
<?= Alert::widget([
'options' => ['class' => ' alert-dismissible alert-'.$type],
'body' => $message
]) ?>
<?php endif ?>
<?php endforeach ?>
</div>
<?php
$form = ActiveForm::begin([
'options' => ['data' => ['pjax' => true]],//'id' => 'content-form'
// more ActiveForm options
]); ?>
<?= $form->field($model, 'content')
->label('Postez un nouveau commentaire')
->textarea(['rows' => 6]) ?>
<?= Html::submitButton('Create comment',
['content' => 'edit','name' =>'Submit','value' => 'create']) ?>
<?php
ActiveForm::end();?>
</div>
<?php Pjax::end()
?>
</div>
4 - the _one-comment view
<div class="one-comment">
<div class="comment-header">
<?php echo $text_header;?>
</div>
<div class="comment-text">
<?php echo $com->content;?>
</div>
<div class="comment-submit">
<?php
if ($with_edit_form)
{
// echo "with edit ".$com->id; exit();
echo $this->render('_update-one-comment',(['com' =>$com]));
} else
{
if($submit_btn){
$form = ActiveForm::begin([
'options' => [ 'data' => ['pjax' => true]],//'name' => 'one','id' => 'com-form-'.$com->id,
// more ActiveForm options
]); ?>
<?= $form->field($com, 'id')->hiddenInput()->label(false);?>
<div class="form-group">
<?= Html::submitButton('', [
'class' => 'glyphicon glyphicon-pencil sub-btn',
'content' => 'edit',
'name' =>'Submit','value' => 'edit']) ?>
</div>
<?php
ActiveForm::end();
}
}?>
</div>
</div>
5 the _update-one-comment form
//echo 'dans update-one-comment';print_r($com->toArray()); exit();
$form = ActiveForm::begin([
'options' => [ 'data' => ['pjax' => true]],//'name' => 'edit-one','id' => 'edit-com-form-'.$com->id,
// more ActiveForm options
]); ?>
<?= $form->field($com, 'id')->hiddenInput()->label(false);?>
<?= $form->field($com, 'created_at')->hiddenInput()->label(false);?>
<?= $form->field($com, 'updated_at')->hiddenInput()->label(false);?>
<?= $form->field($com, 'content')
->label('Mise à jour commentaire')
->textarea(['rows' => 6]) ?>
<div class="form-group">
<?= Html::submitButton($com->isNewRecord ?
Yii::t('app', 'Create comment') :
Yii::t('app', 'Update comment'), ['class' => $com->isNewRecord ?
'btn btn-success' :
'btn btn-primary','name' =>'Submit','value' => 'update']) ?>
</div>
<?php
ActiveForm::end();
?>
6- the Post model 's addComment()
public function addComment($comment, $up=false)
{
if(Yii::$app->params['commentNeedApproval'])
{$comment->status=Comment::STATUS_PENDING;}
else {$comment->status=Comment::STATUS_APPROVED;}
$comment->post_id=$this->id;
$comment->user_id=Yii::$app->user->identity->id;
if($up){
$test=$comment->update();
if($test) {//($comment->save(false)){
Yii::$app->session->setFlash('success',Yii::t(
'app','The comment has been succesfully updated.'));
return true;
}
Yii::$app->session->setFlash('failure',Yii::t(
'app','The comment could not be updatded.'));
} else
{ //création
if($comment->save()){
Yii::$app->session->setFlash('success',
Yii::t('app','The comment has been succesfully recorded.'));
return true;
}
Yii::$app->session->setFlash('failure',
Yii::t('app',$up.false.'The comment could not be recorded.'));
}
return false;
}
Why are you counting on the submit button name / value to figure out what you need to do?
$_POST['Comment']['id'] is a much better indicator of what needs to done. If it is there update otherwise create.
Also make sure the model does not allow editing of comments posted by others.
The model should not set flash messages, that is a job for the controller.
"I can update an existing comment an infinite number of times." of course you can, from what you told us there is nothing that would say you should not be able to. And you are not checking to prevent that.
As the submit button's value is not always transmitted in the post (it works with Chromium but not with Firefox), I solved my problem adding a hidden field in the forms and used it instead of the submit button's value.

How to set validation rules for custom CActiveRecord attributes in Yii?

I'm working on a Yii project with a database, that contains a table, where almost all it's data is saved in a field as JSON (it's crazy, but it is so as it is):
id INTEGER
user_id INTEGER
data LONGTEXT
This "JSON field" data has following structure and contains inter alia an image:
{
"id":"1",
"foo":"bar",
...
"data":{
"baz":"buz",
...
}
}
Displaying it is no problem, but now I want to make the data ediable. My form looks like this:
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'my-form',
'htmlOptions' => array('enctype' => 'multipart/form-data'),
'enableAjaxValidation'=>false,
));
?>
<div class="row">
<?php echo $form->labelEx($model, 'foo'); ?>
<?php
echo $form->textField($model, 'foo', array(...));
?>
<?php echo $form->error($model, 'foo'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model, 'baz'); ?>
<?php
echo $form->textField($model, 'data[baz]', array(...));
?>
<?php echo $form->error($model, 'data[baz]'); ?>
</div>
It works. But there are multiple problems, that seem to be caused by the same thing -- that he form fields are not referenced to the model attributes/properties:
When I make fields foo and baz required (public function rules() { return array(array('foo, baz', 'required')); } -- the property $foo is defined) foo bahaves as wished, but baz causes an "foo cannot be blank" error. So I cannot set a data[*] as required.
If the form is not valid and gets reloaded, all the data[*] fields are empty.
The data[*] fields are not marked as required.
Is there a to solve this without to change the datase structure? There will not be a correct way for it, but maybe a workaround.
It's impossible to validate fields in such way. First of all if you are using field in model it must be defined or exist in table for active record. So if you want to validate such structure the only right way to do it:
class Model extends CActiveRecord {
// Define public varialble
public $data_baz;
public function rules(){
return array(
// Add it to rules
array( 'data_baz', 'required' )
);
}
public function attributeLabels(){
return array(
// Add it to list of labels
'data_baz' => 'Some field'
);
}
protected function beforeSave(){
if ( !parent::beforeSave() ) {
return false;
}
// Also you may create a list with names to automate append
$this->data['baz'] = $this->data_baz;
// And serialize data before save
$this->data = serialize( $this->data );
return true;
}
}
And your form should looks like
<div class="row">
<?php echo $form->labelEx($model, 'data_baz'); ?>
<?php echo $form->textField($model, 'data_baz'); ?>
<?php echo $form->error($model, 'data_baz'); ?>
</div>

Passing variables in PHP Zend Framework

I think I have just been working too long and am tired. I have an application using the Zend Framework where I display a list of clubs from a database. I then want the user to be able to click the club and get the id of the club posted to another page to display more info.
Here's the clubs controller:
class ClubsController extends Zend_Controller_Action
{
public function init()
{
}
public function indexAction()
{
$this->view->assign('title', 'Clubs');
$this->view->headTitle($this->view->title, 'PREPEND');
$clubs = new Application_Model_DbTable_Clubs();
$this->view->clubs = $clubs->fetchAll();
}
}
the model:
class Application_Model_DbTable_Clubs extends Zend_Db_Table_Abstract
{
protected $_name = 'clubs';
public function getClub($id) {
$id = (int) $id;
$row = $this->fetchRow('id = ' . $id);
if (!$row) {
throw new Exception("Count not find row $id");
}
return $row->toArray();
}
}
the view:
<table>
<?php foreach($this->clubs as $clubs) : ?>
<tr>
<td><a href=''><?php echo $this->escape($clubs->club_name);?></a></td>
<td><?php echo $this->escape($clubs->rating);?></td>
</tr>
<?php endforeach; ?>
</table>
I think I am just getting confused on how its done with the zend framework..
in your view do this
<?php foreach ($this->clubs as $clubs) : ?>
...
<a href="<?php echo $this->url(array(
'controller' => 'club-description',
'action' => 'index',
'club_id' => $clubs->id
));?>">
...
That way you'll have the club_id param available in index action of your ClubDescription controller. You get it like this $this->getRequest()->getParam('club_id')
An Example:
class ClubsController extends Zend_Controller_Action
{
public function init()
{
}
public function indexAction()
{
$this->view->assign('title', 'Clubs');
$this->view->headTitle($this->view->title, 'PREPEND');
$clubs = new Application_Model_DbTable_Clubs();
$this->view->clubs = $clubs->fetchAll();
}
public function displayAction()
{
//get id param from index.phtml (view)
$id = $this->getRequest()->getParam('id');
//get model and query by $id
$clubs = new Application_Model_DbTable_Clubs();
$club = $clubs->getClub($id);
//assign data from model to view [EDIT](display.phtml)
$this->view->club = $club;
//[EDIT]for debugging and to check what is being returned, will output formatted text to display.phtml
Zend_debug::dump($club, 'Club Data');
}
}
[EDIT]display.phtml
<!-- This is where the variable passed in your action shows up, $this->view->club = $club in your action equates directly to $this->club in your display.phtml -->
<?php echo $this->club->dataColumn ?>
the view index.phtml
<table>
<?php foreach($this->clubs as $clubs) : ?>
<tr>
<!-- need to pass a full url /controller/action/param/, escape() removed for clarity -->
<!-- this method of passing a url is easy to understand -->
<td><a href='/index/display/id/<?php echo $clubs->id; ?>'><?php echo $clubs->club_name;?></a></td>
<td><?php echo $clubs->rating;?></td>
</tr>
<?php endforeach; ?>
an example view using the url() helper
<table>
<?php foreach($this->clubs as $clubs) : ?>
<tr>
<!-- need to pass a full url /controller/action/param/, escape() removed for clarity -->
<!-- The url helper is more correct and less likely to break as the application changes -->
<td><a href='<?php echo $this->url(array(
'controller' => 'index',
'action' => 'display',
'id' => $clubs->id
)); ?>'><?php echo $clubs->club_name;?></a></td>
<td><?php echo $clubs->rating;?></td>
</tr>
<?php endforeach; ?>
</table>
[EDIT]
With the way your current getClub() method in your model is built you may need to access the data using $club['data']. This can be corrected by removing the ->toArray() from the returned value.
If you haven't aleady done so you can activate error messages on screen by adding the following line to your .htaccess file SetEnv APPLICATION_ENV development.
Using the info you have supplied, make sure display.phtml lives at application\views\scripts\club-description\display.phtml(I'm pretty sure this is correct, ZF handles some camel case names in a funny way)
You can put the club ID into the URL that you link to as the href in the view - such as /controllername/club/12 and then fetch that information in the controller with:
$clubId = (int) $this->_getParam('club', false);
The 'false' would be a default value, if there was no parameter given. The (int) is a good practice to make sure you get a number back (or 0, if it was some other non-numeric string).

Create a form for uploading images

I want to let users upload images from their drives. Searching around the net, here's what I've found :
The form :
class ImageForm extends BaseForm
{
public function configure()
{
parent::setUp();
$this->setWidget('file', new sfWidgetFormInputFileEditable(
array(
'edit_mode'=>false,
'with_delete' => false,
'file_src' => '',
)
));
$this->setValidator('file', new sfValidatorFile(
array(
'max_size' => 500000,
'mime_types' => 'web_images',
'path' => '/web/uploads/assets',
'required' => true
//'validated_file_class' => 'sfValidatedFileCustom'
)
));
}
}
the action :
public function executeAdd(sfWebRequest $request)
{
$this->form = new ImageForm();
if ($request->isMethod('post'))
if ($this->form->isValid())
{
//...what goes here ?
}
}
the template :
<form action="<?php echo url_for('#images_add') ?>" method="POST" enctype="multipart/data">
<?php echo $form['file']->renderError() ?>
<?php echo $form->render(array('file' => array('class' => 'file'))) ?>
<input type="submit" value="envoyer" />
</form>
Symfony doesn't throw any errors, but nothing is transfered. What am I missing ?
Youre missing an impotant part which is binding the the values to the form:
public function executeAdd(sfWebRequest $request)
{
$this->form = new ImageForm();
if ($request->isMethod('post'))
{
// you need to bind the values and files to the submitted form
$this->form->bind(
$request->getParameter($this->form->getName())
$request->getFiles($this->form->getName())
);
// then check if its valid - if it is valid the validator
// should save the file for you
if ($this->form->isValid())
{
// redirect, render a different view, or set a flash message
}
}
}
However, you want to make sure you set the name format for your form so you can grab a the values and files in the fashion... In your configure method you need to call setNameFormat:
public function configure()
{
// other config code
$this->widgetSchema->setNameFormat('image[%s]');
}
Also in configure you dont need to call parent::setUp()... That is called automatically and is actually what invokes the configure method.
LAstly, you ned to have to correct markup - your emissing the form name from your tag:
<form action="<?php echo url_for('#images_add') ?>" name="<?php echo $form->getName() ?>" method="POST" enctype="multipart/data">
Personally I like to use the form object to generate this as well as it looks cleaner to my eyes:
<?php echo $form->renderFormTag(
url_for('#images_add'),
array('method' => 'post') // any other html attriubutes
) ?>
It will work out the encoding and name attributes based on how youve configured the form.