yii blog comment model with multimodel form - php

I would like to take the blog comment model and turn the form into a mulitimodel form but I have not been able to work this out. Would appreciate if anyone could point me in the right direction.
Taken the design below I want to add another table (OtherModel) off of comment with a FK in comment linking the tables.
Controller
public function actionView()
{
$post=$this->loadModel();
$comment=$this->newComment($post);
$this->render('view',array(
'model'=>$post,
'comment'=>$comment,
));
}
protected function newComment($post)
{
$comment=new Comment;
$otherModel=new OtherModel;
if(isset($_POST['Comment'], $_POST['OtherModel']))
{
$comment->attributes=$_POST['Comment'];
$otherModel->attributes=$_POST['OtherModel'];
if($post->addComment($comment))
{
if($comment->status==Comment::STATUS_PENDING)
Yii::app()->user->setFlash('commentSubmitted','Thank you...');
$this->refresh();
}
}
return $comment;
}
model
public function addComment($comment)
{
$comment->other_id=$otherModel->other_id;
$otherModel->save();
if(Yii::app()->params['commentNeedApproval'])
$comment->status=Comment::STATUS_PENDING;
else
$comment->status=Comment::STATUS_APPROVED;
$comment->post_id=$this->id;
return $comment->save();
}
render form through CJuiTabs
'Comment'=>$this->renderPartial('/comment/_form',array($model->$comment=>),true)
form
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'comment-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,'author'); ?>
<?php echo $form->textField($model,'author',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'author'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'content'); ?>
<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'content'); ?>
</div>
// added otherModel as part of MMF
<div class="row">
<?php echo $form->labelEx($otherModel,'name'); ?>
<?php echo $form->textField($otherModel,'name',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($otherModel,'name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($otherModel,'description'); ?>
<?php echo $form->textArea($otherModel,'description',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($otherModel,'description'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Submit' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->

I think you have a mistake in your code given above: you are trying to use $otherModel variable instead of $comment rendered by your actionView() method.
Have you tried to use examples posted on yiiframework.com? I mean the link you've given in comment to your question. If it does not suit you, I afraid I've misunderstood your question.

I think you should validate both models before saving, otherwise you'd end up with a stale $otherModel record in your database.
protected function newComment($post)
{
$comment=new Comment;
$otherModel=new OtherModel;
if(isset($_POST['Comment'], $_POST['OtherModel']))
{
$comment->attributes=$_POST['Comment'];
$otherModel->attributes=$_POST['OtherModel'];
// also specify $otherModel as a param
if($post->addComment($comment, $otherModel))
{
if($comment->status==Comment::STATUS_PENDING)
Yii::app()->user->setFlash('commentSubmitted','Thank you...');
$this->refresh();
}
}
return $comment;
}
public function addComment($comment, $otherModel)
{
// Validate both models, return false if there are errors.
// Errors should be available via $model->getErrors()
if ($comment->validate() && $otherModel->validate()) {
// save the otherModel first to obtain the generated ID
$otherModel->save();
$comment->other_id=$otherModel->id;
if(Yii::app()->params['commentNeedApproval'])
$comment->status=Comment::STATUS_PENDING;
else
$comment->status=Comment::STATUS_APPROVED;
$comment->post_id=$this->id;
return $comment->save();
} else {
return false;
}
}
Note: You may also use transactions here.

Related

how to insert a form post data into database in yii 1 framework

this is my form in view
<div class="form">
<?php echo CHtml::errorSummary($model); ?>
<div class="row">
<?php echo CHtml::activeLabel($model,'Your Name'); ?>
<?php echo CHtml::activeTextField($model,'regname') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'Your Password'); ?>
<?php echo CHtml::activePasswordField($model,'regpass') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'Email Address'); ?>
<?php echo CHtml::activePasswordField($model,'regemail') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'Contact'); ?>
<?php echo CHtml::activePasswordField($model,'regcontact') ?>
</div>
<div class="row submit">
<?php echo CHtml::submitButton('Login'); ?>
</div>
please help me to save this data from my controller to model
this is my model
//-- set Table
public function tableName(){
return 'user';
}
public function attributeLabels()
{
return array(
'username'=>'Your username for the game',
'password'=>'Your password for the game',
'email'=>'Needed in the event of password resets',
);
}
and this is my controller
public function actionRegister2()
{
$model=new RegisterForm;
if(isset($_POST['RegisterForm']))
{
echo 'done';
}
$this->render('register2',array(
'model'=>$model,
));
i an new in yii framework so didn't get a good tutorial for it, please suggest me how i insert the data into database by submitting a form
you can add this code in your controller:
public function actionRegister2()
{
$model=new RegisterForm;
if(isset($_POST['RegisterForm']))
{
$model->attributes = $_POST['RegisterForm'];
if ($model->save()) {
Yii::app()->user->setFlash('success', 'You have successfully added.');
$this->redirect(array('index'));
}
// or if(!$model->save()){ print_r($model->getErrors())}
}
$this->render('register2',array(
'model'=>$model,
));
}

Yii form submition with CActiveForm

i just need to do a registration form, i'm battling with completing this task with CActiveForm. Basically its just inserting a new db record on form submit. This is what i have,
MyView
<!--begin a form-->
<?php $form = $this->beginWidget('CActiveForm', array(
'id'=>'user-registration-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'focus'=>array($model,'firstName'),
)); ?>
<!--error handling-->
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'firstName'); ?>
<?php echo $form->textField($model,'firstName'); ?>
<?php echo $form->error($model,'firstName'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'lastName'); ?>
<?php echo $form->textField($model,'lastName'); ?>
<?php echo $form->error($model,'lastName'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'age'); ?>
<?php echo $form->textField($model,'age'); ?>
<?php echo $form->error($model,'age'); ?>
</div>
<?php $this->endWidget(); ?>
<!--end a form-->
My Controller that renders the above view, this where i'm stuck, I also created a model called User(haven't done any code in it, default)
class RegisterController extends Controller
{
public function actionIndex()
{
$model = User::
$this->render('index', array('model'=>$model));
}
}
From my research i found there is something like, jst dnt know how to use it
link
$post=new Post;
$post->title='sample post';
$post->content='post body content';
$post->save();
Thanks in advance
You need to do in your actionIndex:
public function actionIndex()
{
$model = new User;
if(isset($_POST['User']))
{
$model->attributes = $_POST['User'];
if($model->save())
//Do any stuff here. for example redirect to created user view.
}
$this->render('index', array('model'=>$model));
}
I recommend you to read the Building a blog system with Yii tutorial. This is very good resource for learning yii better and also learn you the most important parts of any web application.

Setting default values and Creating into Database using Yii

I'm trying to create a new user but I'm having trouble trying to create the user because some of the values that are needed to create a user must be default values that I'm not quite sure how to set. I also need to input into a different table while the actual "create" happens from a different controller.
Here is my form code:
<?php
/* #var $this SystemUserController */
/* #var $model SystemUser */
/* #var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'system-user-form',
'enableAjaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<!--
<div class="row">
<?php echo $form->labelEx($model,'party_id'); ?>
<?php echo $form->textField($model,'party_id',array('size'=>20,'maxlength'=>20)); ?>
<?php echo $form->error($model,'party_id'); ?>
</div>
!-->
<div class="row" id="toshow" style="display:none" name="suppliers"> <?php $supplier = SupplierHead::model()->findAll();
$list = CHtml::listData($supplier ,'head_id','head_name');
echo $form->DropDownList($model,'party_id',
$list, array('prompt'=>'Select Supplier')); ?>
</div>
<button id="abutton">Already a Supplier</button>
<script>
$(document).ready(function() {
$("#abutton").click(function(e){
e.preventDefault();
$("#toshow").css('display', 'block');
});
});
</script>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username',array('size'=>60,'maxlength'=>200)); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'password'); ?>
</div>
<script>
$("#supplier").click(function () {
$("#suppliers").show("slow");
});
</script>
<!--
<div class="row">
<?php echo $form->labelEx($model,'date_last_login'); ?>
<?php echo $form->textField($model,'date_last_login'); ?>
<?php echo $form->error($model,'date_last_login'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'status'); ?>
<?php echo $form->textField($model,'status',array('size'=>50,'maxlength'=>50)); ?>
<?php echo $form->error($model,'status'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'date_created'); ?>
<?php echo $form->textField($model,'date_created'); ?>
<?php echo $form->error($model,'date_created'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'date_modified'); ?>
<?php echo $form->textField($model,'date_modified'); ?>
<?php echo $form->error($model,'date_modified'); ?>
</div>
--!>
<div class="row">
<?php echo $form->labelEx($model,'user_role'); ?>
<?php echo $form->textField($model,'user_role',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'user_role'); ?>
</div>
<!--
<div class="row">
<?php echo $form->labelEx($model,'isLogin'); ?>
<?php echo $form->textField($model,'isLogin'); ?>
<?php echo $form->error($model,'isLogin'); ?>
</div>
--!>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
As you can see, I've commented out the attributes that I don't want to use. I also fixed the SystemUser model attributes rules() to define which attributes won't be needed for user input here:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('party_id, username, password', 'required'),
//array('isLogin', 'numerical', 'integerOnly'=>true),
array('party_id', 'length', 'max'=>20),
array('username', 'length', 'max'=>200),
array('password, user_role', 'length', 'max'=>255),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('party_id, username' 'on'=>'search'),
);
}
Finally, there's also a drop down list I included above from the form that is required to be inserted into a model of a different controller. How do I go about this?
The attributes that need default values are as follows:
date_last_login
status
date_created
date_modified
EDIT
I've uploaded a picture of what happens when I select "Create"
I decided not to add defaults try keeping them NULL just to see if the rules() would work. I
Any help?
Yii's model has methods such as:
beforeSave()
afterSave()
beforeValidate()
afterValidate()
and so on ...
which can be overridden into your model. If you want to set any default value before saving/validating you can use from mentioned methods in your model. Please take a look at the following example:
public function beforeSave() {
if (parent::beforeSave()) {
//Example
$this->date_modified=new New CDbExpression('NOW()');
//ANOTHER EXAMPLE
$this->date=date('Y-m-d',time());
// YOU CAN EVEN CALLING A WEBSERVICE
// ANYTHING THAT YOU WANT TO DO BEFORE SAVING INTO DATABASE
return true;
}
}
other methods such as afterSave and ... work like above.
I hope it help :)
You can use the rules for it like
public function rules()
{
return array(
// your other rules
array('myField','default','value'=>'my Name'),
// for date type use new CDbExpression('NOW()')
array('date_modified','default',
'value'=>new CDbExpression('NOW()'),
),
// rest of your rules
);
}
Try with this data type:
date_last_login : timestamp
status : enum('active','inactive')
date_created : timestamp
date_modified : timestamp
Defult Time stamp: current_timestamp

Yii: How to update multiple models using only 1 form 1 model and 1 action?

I have a model website and a model url.
Each url data is attached to a website data. A url is related to a website via a website_id.
On my web app, I need to check the data before accepting it.
I want to see on screen the entire data regarding a url data and I managed to do this.
Now, I also want to update the entire data that is listed on screen.
On screen I have the entire url data and website data, but when I try to save the data, the website data is empty.
My logic was to add to the url model a property: public $website;
And within the url model, a method aftersave:
protected function afterSave() {
$w = null;
$w = Website::model()->findByAttributes(array('id' => $this->website_id));
//echo '<pre>';
//print_r($w);
print_r($this->website);
$w->link = $this->website['link'];
$w->domain = $this->website['domain'];
$w->description = $this->website['description'];
$w->save(false);
die;
return parent::afterSave();
}
and here is the important code from the _form file:
<div class="row">
<?php echo $form->labelEx($model,'will_expire'); ?>
<?php echo $form->dropDownList($model,'will_expire',array(0=>'No',1=>'Yes')); ?>
<?php echo $form->error($model,'will_expire'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'link'); ?>
<?php echo $form->textField($model_website,'link'); ?>
<?php echo $form->error($model_website,'link'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'domain'); ?>
<?php echo $form->textField($model_website,'domain'); ?>
<?php echo $form->error($model_website,'domain'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'description'); ?>
<?php echo $form->textField($model_website,'description'); ?>
<?php echo $form->error($model_website,'description'); ?>
</div>
There are few questions:
Is the relation url and website being defined in the model such that $url->website of a existing url gives you valid website record?
You form shows, you are not using any website_id, means that you are creating a new website record for every URL, means $w = Website::model()->findByAttributes(array('id' => $this->website_id)); will always return NULL
I assume you have defined a relation of website within your URL model.
Suggested function from my understanding:
protected function afterSave() {
//data is already assigned by the caller
$w = null;
$w = Website::model()->findByAttributes(array('id' => $this->website_id));
if($w)
{
Yii::log("updating existing website data","info");
$this->website->save();
}
else
{
Yii::log("creating new website data","info");
$this->website->save();
$this->website_id = $this->website->website_id;
$this->update(array('website_id')); //save the relation
Yii::log("created new website {$this->website_id}","info");
}
return parent::afterSave();
}
It turned out to be small mistakes like w instead of W, object property instead of array;
Ok, so let me teach you how to do this;
I have 2 models: Url and Website.
Url model has a foreign key website_id and a relation to model Website;
Within the Url model I have a property called website and i declared it like: public $website = array();;
The data gets added thru a bookmarklet that uses a API so the data will be there when the admin comes to update/check it;
In the Url model i have a method afterSave:
protected function afterSave() {
$w = null;
$w = Website::model()->findByAttributes(array('id' => $this->website_id));
if($w)
{
$w->link = $this->website['link'];
$w->domain = $this->website['domain'];
$w->description = $this->website['description'];
$w->save();
}
return parent::afterSave();
}
where $this->website gets populated in the UrlController on actionUpdate like:
public function actionUpdate($id, $type = 'update') {
$model = $this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Url'])) {
$model->attributes = $_POST['Url'];
$model->website = $_POST['Website'];
if ($model->save())
if ($type == 'update')
$this->redirect(array('view', 'id' => $model->id));
else
$this->redirect(array('/admin/url/approvePublicLink'));
}
$model_website = Website::model()->findByAttributes(array('id'=>$model->website_id));
$this->render('update', array(
'model' => $model,
'model_website' => $model_website,
));
}
and gets passed to the afterSave method later;
this is the _update view:
<div style="padding:20px 20px;">
<h1>Update Url, Website, Keywords ...</h1>
<?php echo $this->renderPartial('_form', array(
'model'=>$model,
'model_website' => $model_website,
)); ?>
</div>
and this is the _form view that gets rendered partial:
<div class="form">
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'url-form',
'enableAjaxValidation'=>false,
));
?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'website_id'); ?>
<?php echo CHtml::link($model->relation_website->domain,$model->relation_website->domain,array('class'=>'avia','target'=>'_blank')); ?>
<?php echo $form->error($model,'website_id'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'link'); ?>
<?php echo $form->textField($model,'link',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'link'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'title'); ?>
<?php echo $form->textField($model,'title',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'title'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'description'); ?>
<?php echo $form->textField($model,'description',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'description'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'important'); ?>
<?php echo $form->dropDownList($model,'important',array(0=>'Normal',1=>'Important')); ?>
<?php echo $form->error($model,'important'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'views'); ?>
<?php echo $form->textField($model,'views'); ?>
<?php echo $form->error($model,'views'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'created'); ?>
<?php echo $model->created; ?>
<?php echo $form->error($model,'created'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'updated'); ?>
<?php echo $model->updated; ?>
<?php echo $form->error($model,'updated'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'will_expire'); ?>
<?php echo $form->dropDownList($model,'will_expire',array(0=>'No',1=>'Yes')); ?>
<?php echo $form->error($model,'will_expire'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'link'); ?>
<?php echo $form->textField($model_website,'link'); ?>
<?php echo $form->error($model_website,'link'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'domain'); ?>
<?php echo $form->textField($model_website,'domain'); ?>
<?php echo $form->error($model_website,'domain'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model_website,'description'); ?>
<?php echo $form->textField($model_website,'description'); ?>
<?php echo $form->error($model_website,'description'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'status'); ?>
<?php echo $form->dropDownList($model,'status',array(-1=>'Banned',0=>'Normal',1=>'Active')); ?>
<?php echo $form->error($model,'status'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
I hope it helps.

CForm and its behaviors do not have a method or closure named "beginWidget"

I am quite new in using Yii Fraework and I am trying to implement a custom form with the skeletron from the contact form demo withon the blog demo from Yii Framework. I did almost exactly the same view,, controller and model as the respective form, only that I get the following 500 error:
Error 500
CForm and its behaviors do not have a method or closure named "beginWidget".
Here are the : Controller:
<?php
class CustomController extends Controller {
public function actionSubmit()
{
$model = new CustomForm;
$form = new CForm('application.views.custom._form', $model);
$this->pageTitle = "ffffffffffff";//['title'] = "Authentication";
if($form->submitted('submit') && $form->validate())
$this->redirect(array('blog/index'));
else
$this->render('_form', array('form'=>$form));
}
public function getGenders()
{
return array(
0 => 'Male',
1 => 'Female');
}
}
?>
The Model:
<?php
class CustomForm extends CFormModel {
public $firstName;
public $LastName;
public $phone;
public $address;
public $gender;
public $email;
public function rules()
{
return array(
array('firstName, lastName, gender', 'required'),
array('email', 'email')
);
}
}
?>
The view:
<?php
$this->pageTitle=Yii::app()->name . ' - Custom Form';
$this->breadcrumbs=array(
'Custom Form',
);
?>
<h1>Custom Form</h1>
<?php if(Yii::app()->user->hasFlash('custom')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('custom'); ?>
</div>
<?php else: ?>
<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'custom-form',
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'firstName'); ?>
<?php echo $form->textField($model,'firstName'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'lastName'); ?>
<?php echo $form->textField($model,'lastName'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'email'); ?>
<?php echo $form->textField($model,'email'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'phone'); ?>
<?php echo $form->textField($model,'phone',array('size'=>60,'maxlength'=>128)); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'gender'); ?>
<?php echo $form->radioButton($model,'gender',array('value'=>'Male')) . 'Male'; ?>
<?php echo $form->radioButton($model,'gender',array('value'=>'Female')) . 'Female'; ?>
<?php echo $form->error($model,'gender'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'address'); ?>
<?php echo $form->textArea($model,'address',array('rows'=>6, 'cols'=>50)); ?>
</div>
<div class="row submit">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
<?php endif; ?>
Any ideas why am I getting this error? What am I doing wrong?
Thanks!
CForm represents a form object that contains form input specifications.
You are passing a view file as parameter to the CForm which wont work.
I guess there is no need for this line:
$form = new CForm('application.views.custom._form', $model);
Please check if it works :)

Categories