I have this code Im trying to save the content and the title from a form I made..It has an id that autoincrement the id number adds in the database but the title and the content isn't/cant be save in the database. Can you please check my code if I've done something wrong? or what I'm lacking at.
Here is my model ContentForm.php
<?php
class ContentForm extends CActiveRecord{
public $content;
public $title;
public function tableName(){
return 'tbl_content';
}
public function attributeLabels()
{
return array(
'contentid' => 'contentid',
'content' => 'content',
'title' => 'title',
// 'email' => 'Email',
// 'usrtype' => 'Usrtype',
);
}
Here is my view content.php
<div>
<p>User: <a href="viewuserpost">
<?php
echo Yii::app()->session['nameuser'];
?>
</a>
</p>
</div>
<h1>Content</h1>
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'contact-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
));
?>
Title:
<div class="row">
<?php
echo $form->textfield($model,'title');
?>
</div>
</br>
Body:
<div class="row">
<?php
echo $form->textArea($model,'content',array('rows'=>16,'cols'=>110));
?>
</div>
<div class="row buttons">
<?php
echo CHtml::submitButton($model->isNewRecord? 'Create':'Save');
?>
</div>
<?php $this->endWidget(); ?>
and here is my content action in my sitecontroller.php
public function actionContent(){
$model=new ContentForm;
if(isset($_POST['ContentForm'])) {
$model->attributes=$_POST['ContentForm'];
if($model->save())
$this->redirect(array('content','contentid'=>$model->contentid));
$this->redirect(array('content','title'=>$model->title));
$this->redirect(array('content','content'=>$model->content));
}
$this->render('content',array('model'=>$model));
}
Please help.
Remove
public $content;
public $title;
from your class.
Yii uses PHP magic methods. And when you add attributes to your class, PHP doesn't call them but references to your explicitly written attributes.
Moreover, you should add some validation, if you use $model->attributes=$_POST['ContentForm'];. Another variant is to use unsecure $model->setAttributes($_POST[ContentForm], false) where false tells Yii to set all attributes, not only that are considered safe.
Note, that attributes is not real Model attribute, this is virtual attribute accessed through magic methods.
Also, you don't need three redirects. This is HTTP redirect to other page. This time, you just should just specify route to model view action and its parameter that is id, for example. Like this $this->redirect(array('content/view','id'=>$model->contentid));.
Of course, simplest way for you is to create new model and controller with actions using Gii.
you may missed rules , add this in your model ContentForm.php
public function rules()
{
return array(
array('content,title', 'safe'),
);
}
For more about model validation
http://www.yiiframework.com/wiki/56/reference-model-rules-validation/
Related
Hi I also had a problem when try to upload picture using this method.
My Action/model:
class Image extends CActiveRecord
{
public $foto;
...
public function rules()
{
return array(
...
array('foto', 'file', 'types'=>'jpg, gif, png'),
...
);
}
}
My Controller:
class ImageController extends Controller
{
public function actionCreate()
{
$model=new Image;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Image']))
{
$model->attributes=$_POST['Image'];
$model->image=CUploadedFile::getInstance($model,'foto');
if($model->save())
$model->foto->saveAs('productimages');
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
}
My view:
<?php $form = $this->beginWidget(
'CActiveForm',
array(
'id' => 'upload-form',
'enableAjaxValidation' => false,
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)
); ?>
<?php echo $form->labelEx($model, 'foto'); ?>
<?php echo $form->fileField($model, 'foto'); ?>
<?php echo $form->error($model, 'foto'); ?>
...
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
But when I run, two problems appeared:
Problem #1:
endWiget() call [SOLVED by Ivan Misic]
ImageController contains improperly nested widget tags in its view "/var/www/html/onlineshop-nimalogos/protected/views/image/_form.php". A CActiveForm widget does not have an endWidget() call.
Problem#2:
Since problem # 1 is solved, came with another problem, the image is not saving at my 'productimages' folder.
Please help me with the problem # 2. Many thanks..
You have somewhere opened redundant CActiveForm widget and you should look into views and partials.
Yii is generting three view files with gii, and these are:
create.php update.php
| |
| |
+-------+-------+
|
|
_form.php
create and update views are rendering the same partial _form, so you should look in all three to find redundant beginWidget call.
The view you supported in your question should be _form.php partial view.
In CListView there is a property called "itemsCssClass" which basically adds HTML class attribute to the Itemwrapper.
What if I like to add an ID or any other htmlOptions how will I do it on that wrapper..?
My code is :
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$model->search(),
'viewData'=>array('x'=>''),
'itemView'=>'_classifieds',
'id'=>'boa_ads',
'itemsCssClass'=>'test'
));
This code will produce this HTML:
<div id="boa_ads" class="list-view">
<div class="summary">Displaying 1-4 of 4 results.</div>
<div class="items"><!-- HERE ID LIKE TO ADD AN ID-->
----ITEMS GOES HERE ----
</div>
</div>
</div>
Thanks for your help in advance
From the Yii's source:
public function renderItems()
{
echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass))."\n";
.....
echo CHtml::closeTag($this->itemsTagName);
}
I just see class attribute is passed to the itemsTagName so you probably have to extend CListView to do it.
You can create a CCustomListView class (inside application/widgets folder) which extends from CListView and overwrite renderItems() function. For example:
<?php
Yii::import("zii.widgets.CListView");
class CCustomListView extends CListView
{
public $itemsHtmlOptions;
/**
* Renders the data item list.
*/
public function renderItems()
{
echo CHtml::openTag($this->itemsTagName, array_merge(array('class'=>$this->itemsCssClass), $this->itemsHtmlOptions))."\n";
$data=$this->dataProvider->getData();
if(($n=count($data))>0)
{
$owner=$this->getOwner();
$viewFile=$owner->getViewFile($this->itemView);
$j=0;
foreach($data as $i=>$item)
{
$data=$this->viewData;
$data['index']=$i;
$data['data']=$item;
$data['widget']=$this;
$owner->renderFile($viewFile,$data);
if($j++ < $n-1)
echo $this->separator;
}
}
else
$this->renderEmptyText();
echo CHtml::closeTag($this->itemsTagName);
}
}
In your view, you can use it like:
<?php $this->widget('application.widgets.CCustomListView', array(
'dataProvider'=> 'your_data_provider',
'itemsHtmlOptions' => array('style' => 'color:blue', 'id' => 'your_id'),
'itemView'=>'your_item_view',
'template'=>'your_template',
)); ?>
So the style which in itemsHtmlOptions will be applied for the listview.
This link is also useful for you: How to extend CListView in order to remove extra yii added markup?
I just wondering how it is possible to copy exact code of Yii Framework demo-blog-contact , downloaded from Yii website to other yii application with same version library and it don't show captcha.
When i go to controller/action page ,it show broken link instead of captcha and when i open broken link image in new page it show another broken link.
I saw this link for common problem of CCaptcha and i checked gd library is up and running and i have function actions() with content of exact same as the link said and i don't define any access control filter in the application.
I saw this link and i don't have permission problem and this link and i don't ajax it.
I did exact same as this link said but no success. any help to show these captcha would be appreciated.
Controller :
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
'page'=>array(
'class'=>'CViewAction',
),
);
}
public function accessRules()
{
return array(
array('allow',
'actions'=>array('create', 'captcha'),
'users'=>array('*'),
));
}
Model :
<?php
class ContactsM extends CFormModel {
public $name;
public $email;
public $subject;
public $body;
public $verifyCode;
/**
* Declares the validation rules.
*/
public function rules()
{
return array(
// name, email, subject and body are required
array('name, email, subject, body', 'required'),
// email has to be a valid email address
array('email', 'email'),
// verifyCode needs to be entered correctly
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),
);
}
public function attributeLabels()
{
return array(
'verifyCode'=>'Verification Code',
);
}
}
View :
<?php $form=$this->beginWidget('CActiveForm'); ?>
<?php echo $form->errorSummary($model); ?>
<?php if(extension_loaded('gd')): ?>
<div class="row">
<?php echo $form->labelEx($model,'verifyCode'); ?>
<div>
<?php $this->widget('CCaptcha'); ?>
<?php echo $form->textField($model,'verifyCode'); ?>
</div>
<div class="hint">Please enter the letters as they are shown in the image above.
<br/>Letters are not case-sensitive.</div>
</div>
<?php endif; ?>
<div class="row submit">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
As i understand from your comment You should Extend your Controller class from CController.
I want to share the fact i have understand :
My problem was :
I used inheritances and father class have some issue , the son class extend it but it do not show any error and i was thinking it works fine but in fact it didn't , i understand it till i used some of father function which in this case was CCaptcha.
Here's a newbie question related to my latest exercise with Yii Framework.
I have a following structure in the database:
CREATE TABLE location(
id INTEGER PRIMARY KEY NOT NULL,
location TEXT);
CREATE TABLE parameter(
id INTEGER PRIMARY KEY NOT NULL,
name TEXT,
value TEXT);
CREATE TABLE temperature(
id INTEGER PRIMARY KEY NOT NULL,
locationId INTEGER,
value REAL NOT NULL,
createDate DATETIME NOT NULL,
FOREIGN KEY(locationId) REFERENCES location(id));
CREATE INDEX idx1_temperature ON temperature (createDate);
I'm trying to create a view containing both location data in a grid, but also a functionality to change a certain value in parameter-table. In practice I would have a list of all possible locations in a grid, in addition to a possibility to change the parameter.value where parameter.name="CURRENT_LOCATION".
What I've gotten so far is:
location/admin.php generating a view:
...
<h2>Change current location</h2>
<?php echo $this->renderPartial('_para', array('model'=>Parameter::model()->find('name="current_location"'))); ?>
<h2>Modify locations</h2>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'location-grid',
'dataProvider'=>$model->search(),
'columns'=>array(
'location',
array(
'class'=>'CButtonColumn',
),
),
));
...
location/_para.php for embedding a form:
<?php
/* #var $this ParameterController */
/* #var $model Parameter */
/* #var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'parameter-form',
'enableAjaxValidation'=>false,
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'value'); ?>
<?php //echo $form->textField($model,'value'); ?>
<?php echo $form->dropDownList($model,'value',CHtml::listData(Location::model()->findAll(), 'id', 'location')); ?>
<?php echo $form->error($model,'value'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
So, what would need is to Save(=update) a given parameter-row, but I just seem not to get it right. I have debugged so far that it seems like the Submit Button causes the Location-controller's actionAdmin-function to be executed. That would be fine by me, if I just could instruct there to save the Parameter-record instead of the Location.
Here's the actionAdmin-function from LocationController.php:
public function actionAdmin()
{
$model=new Location('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Location']))
{
$model->attributes=$_GET['Location'];
}
if(isset($_POST['Parameter']))
{
$model->attributes=$_POST['Parameter'];
if($model->save())
{
$this->redirect(array('view','id'=>$model->id));
}
}
$this->render('admin',array(
'model'=>$model,
));
}
I see a lot to posts covering multi model forms and such, but I just cannot get a grip on this. It may very well be that I'm trying to accomplish this in a totally wrong way.
So, punch me to right direction, please.
Okay so, I think the best thing is to put the method for updating the Parameter in the ParameterController. That makes it easier to implement and is a bit cleaner.
So to do that, change the form code to this:
You might need to adjust the action in the form for it to work, e.g. /admin/parameter/update
<?php
/* #var $this ParameterController */
/* #var $model Parameter */
/* #var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'parameter-form',
'enableAjaxValidation'=>false,
// Check that the action method below is correct
'action' => array('/parameter/update', 'id' => $model->id),
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'value'); ?>
<?php //echo $form->textField($model,'value'); ?>
<?php echo $form->dropDownList($model,'value',CHtml::listData(Location::model()->findAll(), 'id', 'location')); ?>
<?php echo $form->error($model,'value'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
If you have an existing update method in your ParameterController, see if it works as is. If it doesn't or you don't have the update method, try something like this:
public function actionUpdate($id)
{
$model = Parameter::model()->findByPk($id);
if(isset($_POST['Parameter']))
{
$model->attributes=$_POST['Parameter'];
if($model->update())
{
// Below redirects to the previous URL
$this->redirect(Yii::app()->request->urlReferrer);
}
}
}
I changed $model->save() to $model->update() because that won't call the validation rules and make it return false. If you want to validate for some reason, you will need to change the rule so that name and value are only required when creating a new parameter, like this:
array('name, value', 'required', 'on' => 'create'),
And then when you create your new Parameter, you would need to do $model = new Parameter('create');
I need to understand how to build Ajax request in Yii. I searched on the Yii website and found the following article :
http://www.yiiframework.com/wiki/24/
I wrote the code and I tested it on my localhost ? but for some reason it did not work.
For a first attempt I only wanted to do something simple. I wanted to print the result of another action on my page by using Ajax. The text that I want to be displayed is 'Hi'.
This is how mu code looks like for that action:
view/index
<?php
/* #var $this CurrentController */
$this->breadcrumbs=array(
'Current'=>array('/current'),
'index',
);
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'users-index-form',
'enableAjaxValidation'=>true,
)); ?>
<?php
echo CHtml::dropDownList('country_id','', array(1=>'USA',2=>'France',3=>'Japan'),
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('currentController/dynamiccities'), //url to call.
//Style: CController::createUrl('currentController/methodToCall')
'update'=>'#city_id', //selector to update
//'data'=>'js:javascript statement'
//leave out the data key to pass all form values through
)));
//empty since it will be filled by the other dropdown
echo CHtml::dropDownList('city_id','', array());
?>
<?php $this->endWidget(); ?>
</div><!-- form -->
Controller
<?php
class CurrentController extends Controller
{
public function accessRules()
{
return array(
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update','dynamiccities'),
'users'=>array('#'),
),
);
}
public $country_id;
public function actionIndex()
{
$this->render('index');
}
public function actionDynamiccities() /// Called Ajax
{
echo CHtml::tag('option',
array('value'=>'2'),CHtml::encode('Text'),true);
}
}
Unfortunately I'm not getting the desired result. What I get is:
drowpdown list contains country array.
another drowpdown list but empty ?!
How should I fix my example code so it would work? Can anyone see what I am doing wrong?
echo CHtml::dropDownList('city_id','', array());
use id as
echo CHtml::dropDownList('city_id','', array('id'=>'city_id'));