FriendsOfSymfony / FOSTwitterBundle

UNMAINTAINED. Please use HWIOAuthBundle as a replacement for FOSTwitterBundle.
http://friendsofsymfony.github.com/
146 stars 38 forks source link

Save user information in database using FOSTwitterBundle #57

Open naqac opened 11 years ago

naqac commented 11 years ago

I installed FOSTwitterBundle using your tutorial here ,but I have an issue about how to save informations in my database of every user logged using his twitter account ?

I have this error :
_ErrorException: Catchable Fatal Error: Argument 2 passed to Skeleton\PanelBundle\Security\User\Provider\TwitterUserProvider::_construct() must be an instance of FOS\UserBundle\Entity\UserManager, instance of FOS\UserBundle\Doctrine\UserManager given, called in /var/www/skeleton/app/cache/dev/appDevDebugProjectContainer.php on line 1678 and defined in /var/www/skeleton/src/Skeleton/PanelBundle/Security/User/Provider/TwitterUserProvider.php line 34

here is my config.yml :

services: my.twitter.user: class: Skeleton\PanelBundle\Security\User\Provider\TwitterUserProvider arguments: twitter_oauth: "@fos_twitter.api" userManager: "@fos_user.user_manager" validator: "@validator" session: "@session"

and security.yml :

*security: encoders: Symfony\Component\Security\Core\User\User: plaintext

role_hierarchy: ROLE_ADMIN: ROLE_USER ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

providers:

my_fos_twitter_provider:
    id: my.twitter.user 

firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false

public:
    pattern:  /
    fos_twitter:
        login_path: /twitter/login
        check_path: /twitter/login_check
        default_target_path: /
        provider: my_fos_twitter_provider

    anonymous: ~* 

I spend almost all day but no solution!

Baachi commented 11 years ago

Read the error message:

Catchable Fatal Error: Argument 2 passed to Skeleton\PanelBundle\Security\User\Provider\TwitterUserProvider::__construct() must be an instance of FOS\UserBundle\Entity\UserManager, instance of FOS\UserBundle\Doctrine\UserManager given

You're use statement is wrong. Change the use statement will fix your error:

-use FOS\UserBundle\Entity\UserManager;
+use FOS\UserBundle\Doctrine\UserManager;
naqac commented 11 years ago

Thanks but no I get this error :

_ErrorException: Catchable Fatal Error: Argument 4 passed to Skeleton\PanelBundle\Security\User\Provider\TwitterUserProvider::_construct() must be an instance of Symfony\Component\HttpFoundation\Session, instance of Symfony\Component\HttpFoundation\Session\Session given, called in /var/www/skeleton/app/cache/dev/appDevDebugProjectContainer.php on line 1678 and defined in /var/www/skeleton/src/Skeleton/PanelBundle/Security/User/Provider/TwitterUserProvider.php line 34

and here is TwitterUserProvider :

<?php
namespace Skeleton\PanelBundle\Security\User\Provider;

use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\HttpFoundation\Session;
use \TwitterOAuth;
use FOS\UserBundle\Doctrine\UserManager;
use Symfony\Component\Validator\Validator;

class TwitterUserProvider implements UserProviderInterface
{
    /** 
     * @var \Twitter
     */
    protected $twitter_oauth;
    protected $userManager;
    protected $validator;
    protected $session;

    public function __construct(TwitterOAuth $twitter_oauth, UserManager $userManager,Validator $validator, Session $session)
    {   
        $this->twitter_oauth = $twitter_oauth;
        $this->userManager = $userManager;
        $this->validator = $validator;
        $this->session = $session;
    }   

    public function supportsClass($class)
    {   
        return $this->userManager->supportsClass($class);
    }   

    public function findUserByTwitterId($twitterID)
    {   
        return $this->userManager->findUserBy(array('twitterID' => $twitterID));
    }   

    public function loadUserByUsername($username)
    {
        $user = $this->findUserByTwitterId($username);

        $this->twitter_oauth->setOAuthToken($this->session->get('access_token'), $this->session->get('access_token_secret'));

        try {
            $info = $this->twitter_oauth->get('account/verify_credentials');
        } catch (Exception $e) {
            $info = null;
        }

        if (!empty($info)) {
            if (empty($user)) {
                $user = $this->userManager->createUser();
                $user->setEnabled(true);
                $user->setPassword('');
                $user->setAlgorithm('');
            }

            $username = $info->screen_name;

            $user->setTwitterID($info->id);
            $user->setTwitterUsername($username);
            $user->setEmail('');
            $user->setFirstname($info->name);

            $this->userManager->updateUser($user);
        }

        if (empty($user)) {
            throw new UsernameNotFoundException('The user is not authenticated on twitter');
        }

        return $user;
    }

    public function refreshUser(UserInterface $user)
    {
        if (!$this->supportsClass(get_class($user)) || !$user->getTwitterID()) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }

        return $this->loadUserByUsername($user->getTwitterID());
    }
}
Baachi commented 11 years ago

Please read the error message! PHP says you have the wrong use statement. I think you update your symfony2 app, right?

naqac commented 11 years ago

Yes i'm using symfony 2.2.1 the last one...

naqac commented 11 years ago

Here is the problem I guess,this bundle works just with symfony 2.0?

Baachi commented 11 years ago

No, your problem is, that you didn't read the Changelog. The session component has been refactored in symfony 2.1. The new namespace is Symfony\Component\HttpFoundation\Session\Session.

Can you close this issue, its not related to the bundle.

naqac commented 11 years ago

Ok I don't have any error now,but the last issue is that after I login using twitter account I check my table User but is still empty,nothing is stored in database....?!

Baachi commented 11 years ago

Is your project open source? If not, can you debug the problem?

naqac commented 11 years ago

No until now,I don't know how the bundle works to save data in database, I installed FosUserBundle too,I have made all configuration,I have a table in database and en Entity User?So why it dosn't works...?

Baachi commented 11 years ago

I can't help you without any information. Have you checked the logs, if the update statement is fired? If not take a look in the UserManager::updateUser method. Use var_dump and exit to check the values inside this method.

naqac commented 11 years ago

ok i see,just another stupid question,the bundle automatically saves the data during the authentication in DB or I have to create a code for saving using methods of the class TwitterUserProvider?

Baachi commented 11 years ago

Not magical, you wrote the TwitterUserProvider, which invoke the method UserManager::updateUser.

naqac commented 11 years ago

I don't get you without code.I have just this in my action :

$request = $this->get('request'); $twitter = $this->get('fos_twitter.service');

      $authURL = $twitter->getLoginUrl($request);

      $response = new RedirectResponse($authURL);

      return $response;
Baachi commented 11 years ago

I know. But you created a TwitterUserProvider class. This class will be used to load the user from the database. The security component from symfony will call TwitterUserProvider::loadUserByUsername. And this method create a user or update a user with the twitter informations.

So you should debug this method.

naqac commented 11 years ago

Ok I understand that but how,in this method I had "username" in parameter so I must have username of twitter account :

$request = $this->get('request'); $twitter = $this->get('fos_twitter.service'); $authURL = $twitter->getLoginUrl($request); $response = new RedirectResponse($authURL);

$result = new TwitterUserProvider();

$result-> loadUserByUsername($username) ??
  return $response;

can you help me by some code...

naqac commented 11 years ago

I spend two days with this bundle, I can do it by my self insted to use the famous TwitterUserProvider,they are no solution,how I debug this method!!!