2012-04-25 137 views
14

我有一個關於FOSU​​serBundle的Symfony的2.0.x的問題 在那裏的文檔,你可以找到一種方法來改變登錄使用用戶名和電子郵件。這很好!但我想登錄只用電子郵件。所以我在我的CustomUserManager中添加了一個函數(從原來的擴展),確保您只需登錄您的電子郵件。FOSUserBundle登錄與電子郵件(Symfony2的)

namespace Frontend\UserBundle\Model; 

use FOS\UserBundle\Entity\UserManager; 
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 

class CustomUserManager extends UserManager 
{ 
    public function loadUserByUsername($email) 
    { 
     /*$user = $this->findUserByUsernameOrEmail($username); 

     if (!$user) { 
      throw new UsernameNotFoundException(sprintf('No user with name "%s" was found.', $username)); 
     } 

     return $user;*/ 

     //Change it to only email (Default calls loadUserByUsername -> we send it to our own loadUserByEmail) 
     return $this->loadUserByEmail($email); 
    } 

    public function loadUserByEmail($email) 
    { 
     $user = $this->findUserByEmail($email); 

     if (!$user) { 
      throw new UsernameNotFoundException(sprintf('No user with email "%s" was found.', $email)); 
     } 

     return $user; 

    } 
} 

但現在我有一個問題,我需要控制保存在會話中的值。他將我的用戶名保存在會話中,當系統檢查此消息時,不會有電子郵件(因爲他只檢查電子郵件)可用。

所以我的問題是如何/在哪裏可以改變存儲的用戶名變量中的值。

謝謝!

回答

27

這可以通過在用戶實體覆蓋setter方法來完成:

<?php 

namespace Acme\UserBundle\Entity; 

use FOS\UserBundle\Entity\User as BaseUser; 
use Doctrine\ORM\Mapping as ORM; 
use Gedmo\Mapping\Annotation as Gedmo; 

/** 
* @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\UserRepository") 
* @ORM\Table(name="users") 
*/ 
class User extends BaseUser 
{ 

    // ... 

    // override methods for username and tie them with email field 

    /** 
    * Sets the email. 
    * 
    * @param string $email 
    * @return User 
    */ 
    public function setEmail($email) 
    { 
     $this->setUsername($email); 

     return parent::setEmail($email); 
    } 

    /** 
    * Set the canonical email. 
    * 
    * @param string $emailCanonical 
    * @return User 
    */ 
    public function setEmailCanonical($emailCanonical) 
    { 
     $this->setUsernameCanonical($emailCanonical); 

     return parent::setEmailCanonical($emailCanonical); 
    } 

    // ... 

} 

這不是從你的問題不清楚,但是從你的命名空間我假設你有一個使用FOSUserBundle作爲其父包你自己的孩子捆綁(根據FOSUserBundle documentation,例如「b」)。

如果你這樣做,你可以很容易覆蓋形式和模板,以便從UI刪除任何username領域,並與email領域取代它們。由於您已按上述覆蓋了電子郵件設置器,因此username屬性將被正確填充。

雖然這個工作,它不是一個非常好的解決方案。缺點是,你仍然會在數據庫中usernameusernameCanonical列。我們本來想徹底刪除這些,但是這需要在FOSUserBundle(用戶名屬性由\FOS\UserBundle\Model\UserInterface要求,並捆綁代碼依賴於它)太多的變化。

14

我發現了一個非常簡單的解決方案,可能不是最好的,但簡單就是力量! ;)

我在這裏寫下來,以防萬一它是很好的人。

我把供應商的用戶名/電子郵件登錄選項:

在app/conf目錄/ security.yml:

providers: 
    fos_userbundle: 
     id: fos_user.user_provider.username_email 

,然後在登錄表單的觀點我只讓與登錄輸入類型=「電子郵件」:

<input type="email" class="form-control" id="username" placeholder="E-Mail" name="_username" required="required"/> 
+0

嘿,感謝這個NoFlag - 這個工作對我來說是完美的。 我在配置參考中尋找它。但是,因爲這實際上在安全配置中,它不在[FOSUserBundle配置參考](https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md)中。對於我做過的同樣事情的其他人 - 您必須在[FOSUserBundle的安全配置文檔]中查找它(https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/logging_by_username_or_email.md )。 – jfgrissom 2014-06-11 03:41:50

+0

它是html5輸入類型,僅適用於最近的瀏覽器 – 2014-06-18 11:26:32

+1

儘管這樣做並且無論如何都有意義,但請記住,用戶可以打開開發工具並將'type =「email」'更改爲'type =「text」'並且然後使用用戶名登錄。這顯然取決於你的情況,這是否是一個問題。 – bassplayer7 2015-03-02 20:24:55