Yii::app()->user->id; gets name of user not ID - yii

I am trying to get the user id but no luck so far...
echo Yii::app()->user->id;
and
echo Yii::app()->user->getId();
return the name of user which is weird.
Any idea what is wrong?

Yii::app()->user returns a component CWebUser by default.
When you want to get some additional information about user, you need to extend this component.
Create a file WebUser.php in your components folder. (my example below)
class WebUser extends CWebUser {
/**
* Gets the FullName of user
*
* #return string
*/
public function getFullName()
{
return $this->_model->first_name . ' ' .$this->_model->last_name;
}
}
In your config file find section
'components'=>array(
'user'=>array(
'class'=>'WebUser'
)
)
if there is no this section , just create it. And change 'class'=> to WebUser'.

you should have getId function in user Identity

Or you are can use setState:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$record=Users::model()->findByAttributes(array('mail'=>$this->username));
if($record===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if($record->password!==md5($this->password."325"))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id = $record->id;
$this->setState('role', $record->active);
$this->setState('mail', $record->mail);
$this->setState('name', $record->name);
$this->setState('surname', $record->surname);
$this->setState('mobile', $record->mobile);
$this->setState('adress', $record->adress);
$record->count_login += 1;
$record->update();
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
<?php echo Yii::app()->user->name." ".Yii::app()->user->surname; ?>

Use getid function in the Component/Useridentity to get user id and name etc..
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$users=Users::model()->find("email_id='$this->username'");
$this->_id=$users->user_id;
}
public function getId(){
return $this->_id;
}
}

if you want to display it on a views this should do:
echo Yii::$app->user->id;

Related

Why is my User Login no longer working after upgrading to Symfony3

I came along a strange Problem with Symfony 3.
Under Symfony 2 everyhting worked out of the Box (Login).
But under Symfony 3 it doesn't validate at all.
The Doctrine Layer is not Loading my User Object nor the Repository.
Whats going on?
UserProviderInterface was changed to UserLoaderInterface in 2.8 (see doc)
class UserRepository extends EntityRepository implements
UserProviderInterface
class UserRepository extends EntityRepository
implements UserLoaderInterface
This wil fix the problem, you can also delete these functions:
public function refreshUser(UserInterface $user)
public function supportsClass($class)
Ok, short update.
I was able to fix this and would like to share what happened.
After Debuging the complete Login Prozess I stumbled accross the main cause for not beeing able to login.
<?php
// src/AppBundle/Entity/UserRepository.php
namespace AppBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$user = $this->createQueryBuilder('u')
->where('u.username = :username OR u.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery()
->getOneOrNullResult();
if (null === $user) {
$message = sprintf(
'Unable to find an active admin AppBundle:User object identified by "%s".',
$username
);
throw new UsernameNotFoundException($message);
}
return $user;
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(
sprintf(
'Instances of "%s" are not supported.',
$class
)
);
}
return $this->find($user->getId());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class
|| is_subclass_of($class, $this->getEntityName());
}
}
Ok,
this Repository Query Class is actually the reason why it is not working.
After Debuging and Testing I came Along this Code Block in the Class:
Symfony\Bridge\Doctrine\Security\User
/**
* {#inheritdoc}
*/
public function loadUserByUsername($username)
{
if (null !== $this->property) {
$user = $this->repository->findOneBy(array($this->property => $username));
} else {
if (!$this->repository instanceof UserLoaderInterface) {
throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface.', get_class($this->repository)));
}
$user = $this->repository->loadUserByUsername($username);
}
if (null === $user) {
throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
}
return $user;
}
It states that the Repository Class must be an instance of UserLoaderInterface.
But the Documentation from
http://symfony.com/doc/current/cookbook/security/entity_provider.html
states it is an Instance of UserProviderInterface.
so the Login fails as it is not the right Interface implemented.
The Documentation (Cookbook) has an old Information in it, or the Symfony Team just simply forgot about it. ^^(can happen)
Hope this helps someone ^^
For me the issue was that the isEqualTo method of the EquatableInterface (on my User entity) was returning false when it should have been returning true.

Edit profile page with 3 tables - Yii frameworks

I am new on Yii framework, so please i need some help where to start.
What i need is, action and module to display a form to a user, which his will be able to edit is own profile (with profile picture), so i have 3 table
user_account || user_personal || user_general
how can i build a form that insert and update those 3 table at once?
i try this:
This is what i did, but its still not saving the data even into 1 table.
public function actionUpdate() {
$model = new ProfileUpdate();
if(isset($_POST['ProfileUpdate']))
{
$model->attributes = $_POST['ProfileUpdate'];
if($model->validate())
{
$account = new Profile();
$account->userid = Yii::app()->user->id;
$account->name = $model->name;
$account->website = $model->website;
$account->category = $model->category;
$account->save();
$this->redirect('profile');
}
}
model:
class Profile extends CActiveRecord
{
public $userid;
public $name;
public $website;
public $category;
public static function model()
{
return parent::model(__CLASS__);
}
public function tableName()
{
return 'userinfo';
}
public function primaryKey()
{
return 'id';
}
public static function userExists($user)
{
return self::model()->countByAttributes( array('username'=>$user) ) > 0;
}
}
You can use all three models in a single function
for example:
In create function
$model_account = new user_account;
$model_personal= new user_personal;
$model_general = new user_general;
$this->render('create',array(
'model_account'=>$model_account, 'model_personal' => $model_personal, 'model_general' => $model_general
));
here the all three models pass by render to create page.
in form page you can use the every model attributes as fields
Like this
echo $form->textField($model_account,'account_name');
echo $form->textField($model_personal,'email');
echo $form->textField($model_general,'address');
In create function / Update function
$model_account->attributes = $_POST['user_account'];
$model_personal->attributes = $_POST['user_personal'];
$model_general->attributes = $_POST['user_general'];
if($model_account->validate() && $model_personal->validate() && $model_general->validate())
{
$model_account->save();
$model_personal->save();
$model_general->save();
}

Create sql query in sonata admin

I use sonata admin in my project. i created two admin classes exam and student. i want to create an action in exam class that shows all students that should pass the exam after creating a new exam, this is the sql query that i want:
"Select * from student,exam where student.codeAdministration=exam.codeAdministration"
examAdmin.php:
<?php
namespace Exam\ExamBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class ExamAdmin extends Admin
{
////
protected function configureFormFields(FormMapper $formMapper)
{
//////
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
////
}
protected function configureListFields(ListMapper $listMapper)
{
/////
}
protected function configureShowField(ShowMapper $showMapper)
{
//////
}
}
i tried this query without putting the condition of WHERE but it does not work:
protected function configureListFields(ListMapper $listMapper)
{
$query = $this->modelManager->getEntityManager()->createQuery('SELECT s FROM Exam\ExamBundle\Entity\student s');
$listMapper
->add('student', 'sonata_type_model', array('required' => true, 'query' => $query))
}
How can i create this action with this query??
exam.php:
<?php
namespace Exam\ExamBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Exam
{
/**
* #var integer
*/
private $idExam
////////
/**
* #var \Examens\ExamensBundle\Entity\Administration
*/
private $codeAdministration;
//////
public function getIdExam()
{
return $this->idExam;
}
///////
public function setCodeAdministration(\Exam\ExamBundle\Entity\Administration $codeAdministration = null)
{
$this->codeAdministration = $codeAdministration;
return $this;
}
/**
* Get codeAdministration
*
* #return \Exam\ExamBundle\Entity\Administration
*/
public function getCodeAdministration()
{
return $this->codeAdministration;
}
///////
}

YII UserIdentity not being updated per refresh?

I have:
class WebUser extends CWebUser {
private $_balance;
public function getBalance() { return $this->_balance; }
}
The problem is, this getBalance value needs to get updated every time the page is refreshed. But it currently only does this when the user logs in the first time. I will have the same problem if a user gets banned, and he is already logged in.
How do I get around this? In other words, how do I force the stored user states to get refreshed every time the user reloads the page?
Here is the code that sets the actual user:
public function authenticate()
{
$api = new api();
$user = $api->getAccountDetailsByCellNr($this->username);
if (empty($user)) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
}
else {
if(!isset($this->username))
$this->errorCode = self::ERROR_USERNAME_INVALID;
else if($user->password !== md5($this->password) )
$this->errorCode = self::ERROR_PASSWORD_INVALID;
else {
$this->errorCode = self::ERROR_NONE;
$this->setState('balance', $user->balance);
}
}
Overwrite the init() function in your WebUser class.
Something like:
class WebUser extends CWebUser {
...
public function init()
{
parent::init();
$user = $api->getAccountDetailsByCellNr($this->username);
$this->_balance = $user->balance;
}
}

UserIdentity and session issue

I have the following class. But when I try to access the Yii::app()->user->realName; it generates an error.
I can't understand it all. please help!
Following code is the code of my UserIdentity class.
<?php
/**
* UserIdentity represents the data needed to identity a user.
* It contains the authentication method that checks if the provided
* data can identity the user.
*/
class UserIdentity extends CUserIdentity {
public $id, $dmail, $real_name;
/**
* Authenticates a user.
* The example implementation makes sure if the username and password
* are both 'demo'.
* In practical applications, this should be changed to authenticate
* against some persistent user identity storage (e.g. database).
* #return boolean whether authentication succeeds.
*/
public function authenticate() {
$theUser = User::model()->findByAttributes(array(
'email' => $this->username,
// 'password' => $this->password
));
if ($theUser == null) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->id = $theUser->id;
$this->setState('uid', $this->id);
// echo $users->name; exit;
// $this->setState('userName', $theUser->name);
$this->setState("realName",$theUser->fname .' '. $theUser->lname);
$this->errorCode = self::ERROR_NONE;
}
return!$this->errorCode;
}
}
?>
You need to extend the CWebUser class to achieve the results you want.
class WebUser extends CWebUser{
protected $_realName = 'wu_default';
public function getRealName(){
$realName = Yii::app()->user->getState('realName');
return (null!==$realName)?$realName:$this->_realName;
}
public function setRealName($value){
Yii::app()->user->setState('realName', $value);
}
}
You can then assign and recall the realName attribute by using Yii::app()->user->realName.
The protected $_realName is optional, but allows you to define a default value. If you choose not to use it, change the return line of the getRealName method to return $realName.
Place the above class in components/WebUser.php, or anywhere that it will be loaded or autoloaded.
Change your config file to use your new WebUser class and you should be all set.
'components'=>
'user'=>array(
'class'=>'WebUser',
),
...
),