Jump to content

How to login to Facebook (redirect properly) from hook (after save)


Recommended Posts

Hi. I'm trying to implement ability to post to Facebook after saving a page like this:

<?php

class MySocialIntegration extends WireData implements Module {

    public static function getModuleInfo() {

        return array(
            'title' => 'My Social Networks Integration module',
            'version' => 010,
            'summary' => 'An example module',
            'singular' => true,
            'autoload' => true,
        );
    }

    public function init() {
        $this->pages->addHookAfter('save', $this, 'afterSave');
    }

    public function afterSave($event) {
        $page = $event->arguments[0];
        if (($page->template == "portfolio-image") || ($page->template == "portfolio-video")) {
            require 'facebook-php-sdk/src/facebook.php';

            // Create our Application instance (replace this with your appId and secret).
            $facebook = new Facebook(array(
                        'appId' => 'xxxxxxxxxxx',
                        'secret' => 'xxxxxxxxxxxxxxxxxxx',
                    ));

            // Get User ID
            $user = $facebook->getUser();

            // We may or may not have this data based on whether the user is logged in.
            //
            // If we have a $user id here, it means we know the user is logged into
            // Facebook, but we don't know if the access token is valid. An access
            // token is invalid if the user logged out of Facebook.

            if ($user) {
                try {
                    // Proceed knowing you have a logged in user who's authenticated.
                    $user_profile = $facebook->api('/me');
                } catch (FacebookApiException $e) {
                    error_log($e);
                    $user = null;
                }
            }

            // Login  will be needed depending on current user state.
            if ($user) {
                $this->message("Facebook: connected!");
            } else {
                $this->message("Facebook: redirects...");
                $loginUrl = $facebook->getLoginUrl();
                $this->session->redirect($loginUrl);
            }
        }
    }

}
 

If I'm not logged, it's redirecting to facebook login page, and after successfull login redirects back, but $facebook->getUser() still returns 0 (and also on consequent executions). If I do the same in separate php file (changing $this->session->redirect to header('Location: '...), works lika a charm.

Help, please!

  • Like 1
Link to post
Share on other sites

I'm making guesses here, since I've not worked with Facebook's API. But it looks to me like the $facebook->getUser() call only occurs after a page is saved? Since it's redirecting to facebook and then redirecting back, there are two requests involved here. The $facebook->getUser() call here would not execute except before redirecting to facebook. What you might want to do set something in $session to tell the next pageview that you want to get that facebook user.

So before your $this->session->redirect($loginUrl), you might have:

$this->session->hello_facebook = 1; 

Then in your module's init() function:

if($this->session->hello_facebook) {
  $this->session->remove('hello_facebook');
  $user = $facebook->getUser(); 
}
Link to post
Share on other sites

Ryan, thank you! That's the point!

But now I have to move all the action to the init method. Is it possible to get there an object of page being edited or I have to save it in the session?

Code now looks like this:

<?php

class MySocialIntegration extends WireData implements Module {

    public static function getModuleInfo() {

        return array(
            'title' => 'My Social Networks Integration module',
            'version' => 010,
            'summary' => 'An example module',
            'singular' => true,
            'autoload' => true,
        );
    }

    public function init() {
        require_once 'facebook-php-sdk/src/facebook.php';
        $this->facebook = new Facebook(array('appId' => 'xxxx','secret' => 'xxxx'));
        $user = $this->facebook->getUser();
        if ($user) {
            try {
                $user_profile = $this->facebook->api('/me');
            } catch (FacebookApiException $e) {
                error_log($e);
                $user = null;
            }
        }
        $this->session->fb_user=$user;
        if ($user && $this->session->fb_action) {  $this->postToFacebook();  }
        $this->pages->addHookAfter('save', $this, 'afterSave');
    }

    function postToFacebook() {
      $this->session->remove('fb_action');
      $this->message("Facebook: post ");
    }
    
    public function afterSave($event) {
        $page = $event->arguments[0];
        if (($page->template == "portfolio-image") || ($page->template == "portfolio-video")) {
            if ($this->session->fb_user) {
                $this->postToFacebook();
            } else {
                $this->session->remove('fb_user');
                $this->session->fb_action=1;
                $loginUrl = $this->facebook->getLoginUrl();
                $this->session->redirect($loginUrl);
            }
        }
    }

}

 
  • Like 1
Link to post
Share on other sites
But now I have to move all the action to the init method. Is it possible to get there an object of page being edited or I have to save it in the session?

In order to get the page being edited, you would want to hook into something like "ProcessPageEdit::execute" and ask it for the page being edited from its getPage() method, i.e.

public function init() {
  $this->addHookAfter('ProcessPageEdit::execute', $this, 'editPage'); 
}

public function editPage(HookEvent $event) {
  $page = $event->object->getPage(); 
  // $page is the page being edited
}

Another thing I want to mention is that it looks like you are doing a lot with facebook on every single request. Maybe that is necessary, but if it isn't, you might want to look into only init'ing the facebook stuff when certain conditions are met. I don't know what those conditions would be in your case, but just bringing it up. In such a case, you may find it helpful to move most (or all) of your init() code into a ready() function. That ready() function is called automatically when the being being rendered is known, so you could do things like this:

public function ready() {
  if($this->page->template == 'admin') {
    // initialize facebook code
  } 
} 
Link to post
Share on other sites

 Ryan, thank you for your efforts. I wonder how do you find a time to answer all the questions!

Another thing I want to mention is that it looks like you are doing a lot with facebook on every single request.

You're right, but I'm planning to add separate "Share" button next to "Save" (or checkbox would even better, I think. By the way, could you direct please how to do that?), and in that case I may press and may not press it, and it would be strange to have a FB login page popping anyway beforehand ( I'm still in the beginning of learning facebook API, and it seems that I have to pass through login page before first manipulation with facebook).

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...