I am trying to update records in my database. I am following a book but something isnt working.
This is the edit action. On post form action leads to process action.
public function editAction()
{
$userTable = $this->getServiceLocator()->get('UserTable');
$user = $userTable->getUser($this->params()->fromRoute('id'));
$form = $this->getServiceLocator()->get('UserEditForm');
$form->bind($user);
$viewModel = new ViewModel(array(
'form' => $form,
'user_id' => $this->params()->fromRoute('id')
));
return $viewModel;
}
Process action
public function processAction()
{
// Get User ID from POST
$post = $this->request->getPost();
$userTable = $this->getServiceLocator()->get('UserTable');
// Load User entity
$user = $userTable->getUser($post->id);
// Bind User entity to Form
$form = $this->getServiceLocator()->get('UserEditForm');
$form->bind($user);
$form->setData($post);
// Save user
$this->getServiceLocator()->get('UserTable')->saveUser($user);
}
And this is the class UserTable with function save user:
public function saveUser(User $user)
{
$data = array(
'email' => $user->email,
'name' => $user->name,
'password' => $user->password,
);
$id = (int)$user->id;
if ($id == 0) {
$this->tableGateway->insert($data);
} else {
if ($this->getUser($id)) {
$this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('User ID does not exist');
}
}
}
There is no error showing. It passes $this->tableGateway->update and just nothing !
EDIT: I can delete users, add users.
u miss this
if ($form->isValid()) {
$this->getServiceLocator()->get('UserTable')->saveUser($form->getData());
}
After validation you can now retrieve validate form data with $form->getData().
Also note that because of binding entity to form via $form->bind($user) $form->getData() is an instance of User
Hope it helps ;)
I dont know why but i must check if form is valid.
if($form->isValid()){
// do the save
}
Related
I have two submit buttons (submit1 and submit2). When I click "submit2", the controller should write a value (1) in a specific column (abgerechnet) in my db.
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if(isset($_POST['submit2']) )
{
$request = Yii::$app->request;
$test= $request->post('test', '1');
}
return $this->redirect(['view', 'id' => $model->ID]);
}
return $this->render('update', [
'model' => $model,
]);
}
But when I click the button "submit2" the column "test" remains empty.
With the lines $request = Yii::$app->request;
$test= $request->post('test', '1');
it should write the value in the column "test".
If you want update the colum abgerechnet in your model based on $_POST['submit2'] then you should set the the value before invoking model->save()
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) ) {
if(isset($_POST['submit2']) )
{
$model->abgerechnet = 1;
}
$model->save();
return $this->redirect(['view', 'id' => $model->ID]);
}
return $this->render('update', [
'model' => $model,
]);
}
i want to have a form, where a logged in user can change his user data. Optionally he can insert a new password. I tried to remove the inputfilter of the 'password' and 'passwordVerification' fields, if the posted password is empty, but i don't know how to handle the save in my service, that the password gets not overwritten...
Controller action
public function indexAction() {
$identity = $this->authentication()->getIdentity();
$userService = $this->userService;
$form = $this->userForm;
$form->bind($identity);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->get('password')->getValue() == '') {
$validationGroup = $form->getValidationGroup();
$passwordKey = array_search('password', $validationGroup);
$passwordVerificationKey = array_search('passwordVerification', $validationGroup);
unset($validationGroup[$passwordKey]);
unset($validationGroup[$passwordVerificationKey]);
$form->setValidationGroup($validationGroup);
$form->getInputFilter()->remove('password');
$form->getInputFilter()->remove('passwordVerification');
}
if ($form->isValid()) {
$userService->saveUser($form->getData());
$this->flashMessenger()->addSuccessMessage('Data has been saved successfully');
return $this->redirect()->toRoute('admin/account');
}
}
return array(
'userForm' => $form
);
}
User service
public function saveUser(User $user) {
if ($password = $user->getPassword()) {
$user->setPassword($this->authenticationService->getAdapter()->getBcrypt()->create($password));
}
$this->userRepository->save($user);
}
when i'm doing this i use a use an unmapped password property (e.g. passwordForm) in my user entity which is used in the form so the original password is not overridden. if the passwordForm field is filled you can override the original password with that value
Hi everyone I'm new with Zend Framework 2 , for ruthentification on my project i used this module (( http://samsonasik.wordpress.com/2013/05/29/zend-framework-2-working-with-authenticationservice-and-db-session-save-handler/#comment-5393 )) and i add the field "Role" on data base.
I want to ask how can i make a specific route for any member of user, for example if the user’s Admin when he connect he will be redirected automatically to route “Admin” and if the user’s “visitor” he will be redirected to route “visitor” ???
Thx
/** this function called by indexAction to reduce complexity of function */
protected function authenticate($form, $viewModel)
{
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$dataform = $form->getData();
$this->authService->getAdapter()
->setIdentity($dataform['username'])
->setCredential($dataform['password']);
$result = $this->authService->authenticate();
if ($result->isValid()) {
//authentication success
$resultRow = $this->authService->getAdapter()->getResultRowObject();
$this->authService->getStorage()->write(
array('id' => $resultRow->id,
'username' => $dataform['username'],
'ip_address' => $this->getRequest()->getServer('REMOTE_ADDR'),
'user_agent' => $request->getServer('HTTP_USER_AGENT'))
);
// your userid -> select the role
$role = $this->getRoleUser($resultRow->id);
return $this->redirect()->toRoute('success', array('action' => 'index', 'role'=>$role));
} else {
$viewModel->setVariable('error', 'Login Error');
}
}
}
}
Then into your success page, just perform some actions using the param role
Don't forget to create a function $role = $this->getRoleUser($resultRow->id); to get the role of the user.
To implement roles function
check before this documentation to how to configure and create models/database: http://framework.zend.com/manual/2.1/en/user-guide/database-and-models.html
protected function getRoleUser($userid){
$table = $this->getServiceLocator()->get('User\Model\UserTable');
return $table->find($userid)->current()->role;
}
I'm working on a module that uses sfDoctrineGuard plugin as base (means uses sfDoctrineGuard) so in my module I developed this code:
class UsuariosForm extends sfGuardUserForm {
protected $current_user;
public function configure() {
unset(
$this['is_super_admin'], $this['updated_at'], $this['groups_list'], $this['permissions_list'], $this['last_login'], $this['created_at'], $this['salt'], $this['algorithm']
);
$id_empresa = sfContext::getInstance()->getUser()->getGuardUser()->getSfGuardUserProfile()->getIdempresa();
$this->setDefault('idempresa', $id_empresa);
$this->current_user = sfContext::getInstance()->getUser()->getGuardUser();
$this->validatorSchema['idempresa'] = new sfValidatorPass();
$this->widgetSchema['first_name'] = new sfWidgetFormInputText(array(), array('class' => 'input-block-level'));
$this->widgetSchema['last_name'] = new sfWidgetFormInputText(array(), array('class' => 'input-block-level'));
$this->widgetSchema['username'] = new sfWidgetFormInputText(array(), array('class' => 'input-block-level'));
$this->widgetSchema['email_address'] = new sfWidgetFormInputText(array(), array('class' => 'input-block-level'));
$this->widgetSchema['password'] = new sfWidgetFormInputPassword(array(), array('class' => 'input-block-level'));
$this->widgetSchema['password_confirmation'] = new sfWidgetFormInputPassword(array(), array('class' => 'input-block-level'));
$this->validatorSchema['password']->setOption('required', true);
$this->validatorSchema['password_confirmation'] = clone $this->validatorSchema['password'];
$this->widgetSchema->moveField('password_confirmation', 'after', 'password');
$this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_confirmation', array(), array('invalid' => 'The two passwords must be the same.')));
}
public function save($con = null) {
if (sfContext::getInstance()->getActionName() == "create" || sfContext::getInstance()->getActionName() == "new") {
$new_user = parent::save($con); /* #var $user sfGuardUser */
$new_user->addGroupByName('Monitor');
}
return $new_user;
}
}
The first function allow me to have my own form instead of sfDoctrineGuard plugin form and the second one is a override of save() method for add a default group to the new users I'm creating. I want also add a default idempresa as you may notice (in config() function) but it's not working, maybe I'm doing something wrong or don't know. idempresa is a field stored in a sfGuardUserProfile table and have of course the relations configured and so on. My question here is: what should be the right way to setup the default idempresa in order to set the profile when users are created?
You have to save the $new_user object again: $new_user->save($con)
Also you don't have to check for action_name in the save() method, you can check it the object is new or not. The Objectform has a method for that.
<?php
...
public function save($con = null)
{
$new_user = parent::save($con);
if($this->isNew())
{
$new_user->addGroupByName('Monitor');
$new_user->save($con); //this saves the group
}
return $new_user;
}
...
I'm using AbstractTableGateway and HydratingResultset to do db operations. (with BjyProfiler)
when i post my form data with add action it works, but edit action doesn't work. when i make a bind it works, but i m redirected to the add page because submitting the form resets paramaters coming from route.
here is my code for editAction() (same with Album editAction())
$id = (int)$this->params()->fromRoute('id');
if (!$id) {
return $this->redirect()->toRoute('voyage', array('action'=>'add'));
}
$voyage = $this->getVoyageTable()->getVoyage($id);
$form = new VoyageForm($this->getTypeVoyageTable());
$form->bind($voyage);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getVoyageTable()->saveVoyage($voyage);
// Redirect to list of voyages
return $this->redirect()->toRoute('voyage');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
and my table :
class VoyageTable extends AbstractTableGateway
{
protected $table ='voyages';
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
$this->resultSetPrototype = new HydratingResultSet();
$this->resultSetPrototype->setObjectPrototype(new Voyage());
$this->initialize();
}
[...]
Can sombody help me? How can i fix this problem ? Thanks.
You need to inform the form about the hydrator since ClassMethods is not the default
$form->setHydrator(new ClassMethods());