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;
}
Related
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
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
}
I am using ZF2
I am want to get the user information who has logged into the system. Basically I am having a create_userid and last_update_userid for every table. I want to populate this with the id of the user who has logged in and performing the operations.
I can pass this as a parameter into my operations from the controller; I would like to get this automatically from the system.
I am sure someone else would have thought about this and performed this.
I did some research and found when a class is created to implement ServiceLocatorAwareInterface we can do all sorts of things with the service locator. Also, the servicelocator is set automatically by the MVC engine.
I created the Table to implement ServiceLocatorAwareInterface and I could get the user id of the logged in user.
I have the code below
namespace UserAdmin\Model;
use Zend\Db\TableGateway\TableGateway;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserTable implements ServiceLocatorAwareInterface {
protected $serviceLocator = null;
protected $loggedUser = 0;
protected $tableGateway;
protected $table = "user";
public function __construct( TableGateway $tableGateway ) {
$this->tableGateway = $tableGateway;
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator() {
return $this->serviceLocator;
}
protected function setLoggedUser( ) {
$serviceLocator = $this->getServiceLocator( );
$authService = $serviceLocator->get( 'AuthService' );
if ( $authService->hasIdentity( ) ) {
$this->loggedUser = $authService->getIdentity( )->user_id;
}
}
...
...
public function saveUser ( User $user ) {
if ( $this->loggedUser == 0 ) {
$this->setLoggedUser( );
}
...
...
$data [ 'last_update_userid' ] = $this->loggedUser;
$data [ 'last_update_timestamp' ] = date ( 'Y-m-d H:i:s' );
if ( is_null( $user_id ) ) {
$data [ 'create_userid' ] = $this->loggedUser;
$data [ 'create_timestamp' ] = date ( 'Y-m-d H:i:s' );
$this->tableGateway->insert( $data );
} else {
if ( $this->getUser ( $user_id ) ) {
$this->tableGateway->update( $data, array ( 'user_id' => $user_id, ) );
} else {
throw new \Exception ( "Could not find row in table $this->table for update" );
}
}
}
}
This takes care of most of my needs. There is just two aspects.
a> I tried calling the setLoggedUser function from the constructor and it does not work. I think the service locator is set after the entire construction. so I am calling the function just before a save, and that is when I need it. Is this a clean implementation or is there another way to do this.
b> An User can register himself on the site; and the userid is an autogenerated sequence so how do I populate the userid to be the same as the new userid.
Two things come to my mind;
1> After insert read the user record and update the record with the userid
2> Not worry about this so much and have a system superadmin id as the id to write users who self register.
This is a problem only for self registrations of users only. Any other table within the system will be inserted or updated only after the user is logged in.
To set the Service Locator in the UserTable Class -
In UserAdmin/Module.php -
'UserAdmin\Model\UserTable' => function($sm) {
$tableGateway = $sm->get('UserTableGateway');
$table = new UserTable($tableGateway);
//This way the serviceLocator is injected to the Table.
$table->setServiceLocator($sm);
return $table;
},
Now, when you will call the setLoggedUser from the controller, the value will be set.
Important:
Rather than having the above private function, the best approach will be to have a Controller Plugin. This plugin will check if any user is logged in or not and if yes then return the user's id.
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());
Hi I created two modules first application second comment.
Idea is to use comment module(Widget) in any application action (website page).
Application module
Test controller
public function commentAction(){
//seting redirection for form
$this->getCommentService()->setRedirection('test/comment');
$list = $this->forward()->dispatch('comment_controrller', array('action' => 'list'));
$add = $this->forward()->dispatch('comment_controrller', array('action' => 'add'));
$view = new ViewModel();
$view->addChild($list, 'list');
$view->addChild($add, 'add');
return $view;
}
View
Comment module
Comment controller
public function addAction()
{
$form = new CommentForm();
$form->get('submit')->setAttribute('value', 'Add');
$request = $this->getRequest();
if ($request->isPost()) {
$comment = new Comment();
$form->setInputFilter($comment ->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$comment ->exchangeArray($form->getData());
$this->getCommentTable()->saveComment($comment);
// Redirect to test controller in application module
return $this->redirect()->toRoute($this->getCommentService()->getRedirection());
}
}
return array('form' => $form);
}
public function listAction()
{
return new ViewModel(array(
$list=> 'test'
));
}
With simple variable (list) all working fine,
Problem I get when trying to redirect form back to comment action in test controller
I can add redirection to test/comment in case form is not valid
but how I will pass all validating errors to test/comment(form)
Can you tell me, if what I'm doing logically correct or in ZF2 we have different way to do widgets
Thanks for help
Answer from weierophinney
http://zend-framework-community.634137.n4.nabble.com/zf2-widget-base-app-logic-td4657457.html
This what I've got so far:
https://github.com/nsenkevich/comment