stop further execution after zend form is not valid and populate the form - zend-form

if the form is not valid then populate the form and stop further execution of code. How to establish this.

Here's what I usually do in my controller:
public function editAction()
{
$model = $this->_findModelFromRequestParams();
$form = new Form_MyModelForm();
$form->populate($model->toArray());
//display the form for the first time and return
if ( ! $this->_request->isPost()) {
$this->view->form = $form;
return;
}
//populate the form with the POST values, and validate.
//If NOT valid, display the form again
if ( ! $form->isValid($this->_request->getPost())) {
$this->view->form = $form;
return;
}
try {
$formData = $form->getValues();
//save the new values here...
//set a flash message and redirect to the view page
$this->_redirect('/model/view/id/' . $model->id);
} catch (Exception $e) {
//there was some sort of error, so set a flash message with the error
//and display the form again. $form is already populated with values
//since we called $form->isValid(), which populated the form
$this->view->form = $form;
}
}

Related

Yii2 UploadImageBehavior. How to remove file?

I have a problem with UploadImageBehavior.
I need to create simple button on frontend part that allow me to remove image (user avatar) after model save.
Actually i know how to do it with unlink, but i absolutely don't understand how to do that via behaviour.
I have next code in rules:
[['avatar'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg, jpeg'],
So Yii just ignore me, if i try to pass null to my avatar property.
Thx )
Just create a method to your model class that does the unlinking, sets the file attribute in your model to null and saves the model.
public function removeAvatar() {
$transaction = $this->getDb()->beginTransaction();
try {
// If this is a new record throw an Exception because no file has been uploaded yet
if($this->isNewRecord) {
throw new \Exception("Can't delete file of new record");
}
// Set the attribute avatar to null
$this->avatar = null;
// Try to save the record. If we can't then throw an Exception
if(!$this->save()) {
throw new \Exception("Couldn't save the model");
}
// Try to delete the file. If we can't then throw an Exception
if(!unlink(Yii::getAlias('#app/path/to/your/file.something')) {
throw new \Exception("Couldn't delete the file");
}
$transaction->commit();
return true;
}
catch(\Exception $e) {
$transaction->rollback();
return false;
}
}
Below works for me:
unlink(getcwd().'/uploads/'.$model->file_id.'/'.$fileModel->file_name.$fileModel->extension);
getcwd() gets the current working directory. The docs for it are here

yii generatepasswordhash not working

For some strange reasons, i am finding it difficult to login with yii->$app->generatePasswordhash($password.) I have a backedn where i register users and also change password. Users can login successfully when i created them but when i edit user password, the system keeps telling me invalid username or password. Below is my code.
//Model
Class Adminuser extends ActiveRecord
{
public $resetpassword
public function activateuser($id,$newpassword)
{
//echo Yii::$app->security->generatePasswordHash($newpassword); exit;
$user = Adminuser::find()->where(['id' =>$id])->one();
$user->status = self::SET_STATUS;
$user->password_reset_token = null;
$user->password = Admin::genPassword($this->resetpassword); // this returns yii::$app->security->generatePasswordHash($password)
return $user->save();
}
}
//controller action
public function actionActivate($id)
{
$model = new Adminuser();
$model->scenario = 'adminactivate';
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if($model->activateuser($id,$model->password))
{
//send a mail
Yii::$app->session->setFlash('success', 'New user has been activated.');
return $this->redirect(['index']);
}
else
$errors = $model->errors;
}
return $this->render('activate', [
'model' => $model,
]);
}
Please i need help
Your activateuser() method has $newpassword as an incoming parameter. Anyway you are using $this->resetpassword in Admin::genPassword(). Looks like that is the reason of the problem and all your passwords are generated based on null value. So try to use $user->password = Admin::genPassword($newpassword); instead.

Yii call CButtonColumn from other widget

i have created new widget to display information in admin view. Final view must be same as CGridView, but with different logic for columns. Everything works fine, except when i try to call CButtonColumn column.
foreach ($this->columns as $column) {
if (is_array($column) && isset($column['class']) {
$this->renderColumnWidget($column);
}
}
/* ... */
protected function renderColumnWidget($column)
{
$widgetClass = $column->class;
unset($column->class);
if (strpos($widgetClass, '.') === false) {
$widgetClass = 'zii.widgets.grid.'.$widgetClass;
}
$this->widget($widgetClass, $column); // Error from here
}
So basically here i check if there is class attribute in column and call that widget. But i get error: CButtonColumn and its behaviors do not have a method or closure named "run".
What am i doing wrong? CButtonColumn don't have run method, and i don't want to extend this class.
You this as a function like this to initiate your columns
protected function initColumns(){
foreach($this->columns as $i=>$column) {
if(is_string($column))
$column=$this->createDataColumn($column);
else {
if(!isset($column['class']))
$column['class']='CDataColumn';
$column=Yii::createComponent($column, $this);
}
if($column->id===null)
$column->id=$id.'_c'.$i;
$this->columns[$i]=$column;
}
foreach($this->columns as $column)
$column->init();
}

Creating nested form in yii

following this link I am trying to create a register form and connect the form to tables "user" and "profile". In my controller I have copied the same code as follows:
public function actionRegistration()
{
$form = new CForm('application.views.user.registerForm');
$form['user']->model = new Users;
$form['profile']->model = new Profile;
if($form->submitted('register') && $form->validate())
{
$user = $form['user']->model;
$profile = $form['profile']->model;
if($user->save(false))
{
$profile->userID = $user->id;
$profile->save(false);
$this->redirect(array('/user/login'));
}
}
var_dump($form->submitted('register'));
$this->render('registration', array('form'=>$form));
}
I actually don't know what is $form->submitted('register') for and why it returns false!
Can anyone explain me what is that and what is 'register' value which is passed to the submitted function!? Also why it should return false while posting the form?
the traditional way to get form data is
$model = new User;
if(isset($_POST["register"])){ //get the form data
...
$model->attributes=$_POST["register"]; //set model's attributes
...
}
for more examples you can go: http://www.yiiframework.com/doc/blog/1.1/en/comment.create

How to set default action dynamically in Yii

i want to change default action of a controller depends on which user is logged in.
Ex. There are two users in my site : publisher and author and i want to set publisher action as default action when a publisher is logged in, and same for author.
what should i do? when can I check my roles and set their relevant actions?
Another way to do this would be setting the defaultAction property in your controller's init() method. Somewhat like this:
<?php
class MyAwesomeController extends Controller{ // or extends CController depending on your code
public function init(){
parent::init(); // no need for this call if you don't have anything in your parent init()
if(array_key_exists('RolePublisher', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='publisher'; // name of your action
else if (array_key_exists('RoleAuthor', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='author'; // name of your action
}
// ... rest of your code
}
?>
Check out CAuthManager's getRoles(), to see that the returned array will have format of 'role'=>CAuthItem object, which is why i'm checking with array_key_exists().
Incase you don't know, the action name will be only the name without the action part, for example if you have public function actionPublisher(){...} then action name should be: publisher.
Another, simpler, thing you can do is keep the default action the same, but that default action simply calls an additional action function depending on what kind of user is logged in. So for example you have the indexAction function conditionally calling this->userAction or this->publisherAction depending on the check for who is logged in.
I think you can save "first user page" in user table. And when a user is authenticated, you can load this page from database. Where you can do this? I think best place is UserIdentity class. After that, you could get this value in SiteController::actionLogin();
You can get or set "first page" value:
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
This is a complete class:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('username' => $this->username));
if ($user === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} else if ($user->password !== $user->encrypt($this->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
// 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(Yii::app()->user->first_page);
}
// display the login form
$this->render('login', array('model' => $model));
}
Also, you can just write right code only in this file. In SiteController file.