Yii Framework: Undefined variable model when checking if guest - php

We have a actionSearchType in our User Controller as follows:
public function actionSearchType()
{
if (Yii::app()->user->isGuest == true)
$this->render('login');
else
$this->render('search_type');
}
Our actionLogin in our User Controller is as follows:
public function actionLogin()
{
$model= new Users();
// if it is ajax validation request
if(isset($_POST['ajax']))
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
$this->redirect(Yii::app()->user->returnUrl);
}
}
// display the login form
$this->render('login',array('model'=>$model));
}
The goal is to ensure that only authenticated users can execute the options on the search type view. When I run this page, I receive an error stating Undefined variable: model.
A snippet of the login view is as follows:
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
What steps must be taken to remedy the above error and properly check to ensure we have an authenticated user?
update
I changed actionSearchType to render the Login Widget per below:
public function actionSearchType()
{
if (Yii::app()->user->isGuest)
$this->widget('ext.LoginWidget');
else
$this->render('search_type');
}
This indeed resolved the error initially seen. A new problem is that there's no styling of the login widget when it renders. Should I echo my tags with appropriate stylesheet classes, or is there a bit more elegant way of doing that?

public function actionSearchType() {
if (Yii::app()->user->isGuest)
$this->redirect('/user/login');
$this->render('search_type');
}
Notes:
to do something when user is guest, simply use if(Yii::app()->user->isGuest) { statement }
to do something when user is logged in, simply use if(!Yii::app()->user->isGuest) { statement }
in the second code, public function actionLogin(), I think you have 2 more closing curly brackets than needed. Anyway, the login action should look like this:
public function actionLogin() {
$formModel = new Login_Form; // Login_Form.php should be in models folder
if (isset($_POST['Login_Form'])) {
$formModel->attributes = $_POST['Login_Form'];
if ($formModel->validate() && $formModel->login()) {
$this->redirect('/'); // replace / with stuff like Yii::app()->user->returnUrl
}
}
$this->render('login', array(
'formModel'=>$formModel,
));
}

Instead of rendering the view redirect to the user login page / action so you don't have to recreate it.
$this->redirect('login');

Somewhere in search_type you are referencing the variable $model which you do not hand over to the render() function. You need to define that variable otherwise the view will create an Exception.
I don't know which Model/Class your search_type view is expecting but you will need to initialize it before you hand it over to the view like this:
$this->render('search_type',array(
'model' => $model,
));
Here a good read about this topic: Understanding the view rendering flow

Related

Yii calling controller function from another controller

In my web application the work flow demands that I should call one controller function from another function
Should I do add extra code or some configuration to proceed ? Right now This is how I implemented .But When I click "save" button nothing is happening values are just getting empty from the form .
My code .I want to create an object of model "BookVegetable" inside "ProducerOfferController" .
My code inside producerOffer controller
public function actionCreate()
{
//$book_vegetable=new BookVegetable;
$model=new BookVegetable;
if(isset($_POST['BookVegetable']))
{
$model->attributes=$_POST['BookVegetable'];
$model->booked_by = Yii::app()->user->id;
$model->save();
if ($model->hasErrors() === false)
{
$this->redirect(Yii::app()->user->returnUrl);
}
}
else
{
Yii::app()->user->setReturnUrl($_GET['returnUrl']);
}
$this->render('book',array('model'=>$model,));
}
My code for from view
<div style='padding-left:50px'>
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array('id'=>'non-ajax_form','enableAjaxValidation'=>false,)); ?>
<p class="help-block">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<?php echo "<br>" ?>
<?php echo CHtml::textField("booked_quantity",$model->booked_quantity); ?>
My scenario
public function actionBookvegetable($id){
$BookVegetable=new BookVegetable;
$model=$this->loadModel($id);
if(isset($_POST['ProducerOffer'],$_POST['BookVegetable']))
{
$model->attributes=$_POST['ProducerOffer'];
$BookVegetable->attributes=$_POST['BookVegetable'];
$BookVegetable->booked_by=Yii::app()->user->id;
$BookVegetable->producer_offer_id=$model->id;
$model->save();
$BookVegetable->save();
if (($model->hasErrors() === false)||($BookVegetable->hasErrors()=== false))
{
$this->redirect(Yii::app()->user->returnUrl);
}
}
else
{
Yii::app()->user->setReturnUrl($_GET['returnUrl']);
}
$this->render('book',array('model'=>$model,'BookVegetable'=>$BookVegetable));
}
<div class="form-actions">
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'type'=>'primary', 'label'=> 'Save',)); ?>
How should I resolve this ? Is it essential to add anything extra to use one controller action inside another controller
The url before saving and its the same after I press save also
http://localhost/xxx/producerOffer/bookvegetable/20?returnUrl=%xxx%2FproducerOffer%2Fmanage
One way to do this in Yii2
Background
In SiteController action index method get the records of all objects from another model called voyzes.
In SiteController
Include the other model ex. Voyzes
Now in the SiteController action index method, implement the code to access the model/SQL/NoSQL or anything and set it in a array and return it to the view. For ex.
Now in the index view you should have your data from another model.
According to your information provided.. when you go here,
http://xxx.yyy.zzz/xxxx/producerOffer/create
Actually it should show you the form of book and when you click the save button there and go to returnUrl.
$this->redirect(Yii::app()->user->returnUrl);
I suggest you to write the following as,
$model->save();
$BookVegetable->save();
if (($model->hasErrors() === false)||($BookVegetable->hasErrors()=== false))
{
$this->redirect(Yii::app()->user->returnUrl);
}
To
if($model->save() && $BookVegetable->save())
$this->redirect('yourAction'); //if params needed, $this->redirect(array('yourAction', 'id' => $model->id));
When you go here, http://xxx.yyy.zzz/xxxx/producerOffer/bookvegetable
What ever the code you have written under ActionBookvegetable will trigger.
To make sure your values submitted properly please change this code
$model->save();
if ($model->hasErrors() === false)
{
$this->redirect(Yii::app()->user->returnUrl);
}
To
if($model->save())
$this->redirect('yourAction');
else
print_r(getErrors());
This will print any errors thats preventing from saving the model. let me know after you try this.
In my work , I have a lot of logic around the "loadModel" routine in controllers to make sure the user logged in has access to the particular model. I found this to work from another controller when I need to access the model, without moving or re-copying the loadmodel routine:
$caseviewController = Yii::app()->createController('Caseview');
//use this method from caseview controller to securley load case view model
$caseview = $caseviewController[0]->loadModel($caseviewid);

YII language selector doesn't make the postback to controller

I'm making a language selector and followed this wiki. I can implement the widget, but when I try the dropdown it doesn't make the postback. For the controller I have the idea that the controller should be: components/Controller.php in stead of components/MyController.php. But anyways both don't work. Does anyone know what to do here? I'm missing something about the essentials of catching a postback here i think..
Controller (components/controller.php):
function init()
{
parent::init();
$app = Yii::app();
if (isset($_POST['_lang']))
{
$app->language = $_POST['_lang'];
$app->session['_lang'] = $app->language;
}
else if (isset($app->session['_lang']))
{
$app->language = $app->session['_lang'];
}
Yii::app()->session['_lang'] = 'anders';
}
widget class (components/LangBox.php):
class LangBox extends CWidget
{
public function run()
{
$currentLang = Yii::app()->language;
$this->render('langBox', array('currentLang' => $currentLang));
}
}
widget view (components/views/langBox.php)
<?php echo CHtml::form(); ?>
<div id="langdrop">
<?php echo CHtml::dropDownList('_lang', $currentLang, array(
'en_us' => 'English', 'is_is' => 'Icelandic'), array('submit' => '')); ?>
</div>
<?php echo CHtml::endForm(); ?>
I am sure your code works ok, but are you actually submitting the form? You should really have a jquery that detects when the dropdown changed and submits it to the server and refreshes the page. Everything else is sound.
I have no idea what 'submit'=>'' does.

Yii Captcha not Changing

My Captcha is not changing, always appear the same word, unless clicking on Reload Captcha button. Why testLimit is not working properly?
Controller.php
public $attempts = 5; // allowed 5 attempts
public $counter;
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xf5f5f5,
'testLimit'=>1,
);
}
private function captchaRequired()
{
return Yii::app()->session->itemAt('captchaRequired') >= $this->attempts;
}
public function actionLogin()
{
if (!Yii::app()->user->isGuest) $this->redirect(array('users/update'));
$model = $this->captchaRequired()? new LoginForm('captchaRequired') : new LoginForm;
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login()) {
$this->redirect(array('users/update'));
} else {
$this->counter = Yii::app()->session->itemAt('captchaRequired') + 1;
Yii::app()->session->add('captchaRequired',$this->counter);
}
}
// display the login form
$this->render('login',array('model'=>$model));
}
View.php
<?php if($model->scenario == 'captchaRequired'): ?>
<br>
<legend><?php echo CHtml::activeLabelEx($model,'verifyCode'); ?></legend>
<div class="control-group">
<div class="controls">
<?php $this->widget('CCaptcha'); ?>
<?php echo CHtml::activeTextField($model,'verifyCode'); ?>
</div>
</div>
<?php endif; ?>
testLimit is the amount of captcha submission, that user can try before generated hash will be changed. Used for avoid typo mistakes.
Verify code stores in session (http://www.yiiframework.com/doc/api/1.1/CCaptchaAction#getVerifyCode-detail), thus be default code can be changed only one of two ways: submit form with testLimit times with incorrect code, or manual update by user.
So you can extends CCaptchaAction class to achieve what you want, f.g. force set $regenerate variable to true.
Is simple solution, use JScript. This script will be reload image captha.
$(document).ready(function () {
setTimeout(function () {
$("img#reviews-verifycode-image").click();
}, 100);
});

Infinite loop trying to validate/save

I'm using Yii framework to create a really simple 1 text-area field and 2 hidden inputs with predefined values sent from the server.
The way it should work is as expected, I mean, you write something on that text-area and you click on the send button. An ajax validation is made (only requisite for the text-area is that is shouldn't be empty) and if validated, save the data and redirect to some other page.
The problem is that it won't save any data if validation error was triggered.
I mean, if I go to the page, write something and hit on the send button, data will be saved and I'll be redirected correctly. But if I go to the page, hit the send button (without typing anything in the text-area), wait for the error to appear (note that this is done via ajax, so no page-reload here), write something and hit send again Yii is going to start making a request after a request in an infinite loop.
I already have checked the data being sent, and everything is fine (both data and action-url).
Here is my Controller code
public function actionView($id)
{
$user = Usuario::model()->findByAttributes(
array(
'nick'=>Yii::app()->user->getId()
)
);
$dataProvider=new CActiveDataProvider('Mensaje', array(
'criteria'=>array(
'with'=>array('usuario', 'usuario.detallesusuario'),
'condition'=>'Tema_idtema='.$id
),
'pagination'=>array(
'pageSize'=>1000,
),
));
$this->render('view',array(
'model'=>$this->loadModel($id),
'usuario_id'=>$user->idusuario,
'tema_id'=>$id,
'dataProvider'=>$dataProvider,
));
}
public function actionCreateMessage(){
$model=new Mensaje;
$this->performAjaxValidation($model);
if(isset($_POST['Mensaje']))
{
$model->attributes=$_POST['Mensaje'];
$model->fecha_hora=new CDbExpression('NOW()');
$model->save();
$this->redirect(array('view', 'id'=>$model->Tema_idtema));
}
}
And the code from the View
<?php
$model = new Mensaje();
echo $this->renderPartial('_mensaje_form', array(
'model'=>$model,
'usuario_id'=>$usuario_id,
'tema_id'=>$tema_id,
),
false, //return instead of echo
true //post-process
);
?>
Here is the "_mensaje_form" code
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'mensaje-form',
'action'=>CHtml::normalizeUrl(array('tema/createMessage')),
'enableAjaxValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>false,
'validateOnType'=>false,
),
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row" style="margin:20px 5px 0 176px;">
<?php echo $form->labelEx($model,'mensaje'); ?>
<?php echo $form->textArea($model,'mensaje',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'mensaje'); ?>
<?php echo $form->hiddenField($model, 'Tema_idtema', array('value'=>$tema_id)); ?>
<?php echo $form->hiddenField($model, 'Usuario_idusuario', array('value'=>$usuario_id)); ?>
</div>
<div class="row buttons" style="margin:-3px 0 -8px 176px;">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Responder' : 'Guardar'); ?>
</div>
<?php $this->endWidget(); ?>
Any idea why I'm getting that loop?
This might help you,
http://www.yiiframework.com/forum/index.php/topic/10427-ajax-clientscript/
in your view, the last parameter "true" in renderPartial may be the problem.
My guess (a bit long shot) that form id in your preformAjaxValidation() might be wrong, so it causes the loop! since it won't get in the body of the if and hence executes Yii::app()->end(); !!
Check it in your controller:
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='exact-form-id')//should be mensaje-form
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}

CodeIgniter Ion_auth check login

how can i check if user logged in or not in view ??
something like this:
if ($this->ion_auth->logged_in())
{
// do something ..
}
else
{
// do something else ..
}
and how can i get user data to variable ?
thanks a lot.
In your controller, you can do something like
function some_method() {
if ($this->ion_auth->logged_in()) {
$loggedin = true;
} else {
$loggedin = false;
}
$data['loggedin'] = $loggedin;
$this->load->view('some_view.php', $data);
}
and then in your view
<?php if ($loggedin): ?>
<p>Logged in</p>
<?php else: ?>
<p>Please log in</p>
<?php endif; ?>
Alternatively, you could just load a different view from your controller if the user is logged in or not.
As stealthyninja said, it should be performed in the controller. You can cut down on the amount of code in your controllers by extending the base CodeIgniter controller, and then have your controller for authenticated areas of your project extend your custom controller. Your custom controller could have a constructor that checks whether or not the user is authenticated and route them appropriately. This same constructor could also set variables within so as to be easily accessible by the custom controller's subclasses.
Controller:
$this->ion_auth->logged_in() ? $data['logged'] = true : $data['logged'] = false;
$this->load->view('index', $data);
View:
<?php if ($logged): ?>
do something...
<?php else: ?>
do something else...
<?php endif; ?>

Categories