I have an ajax multistep form in D7.
When users try to reach step-4, if they are logged-in, they can go on with the form, otherwise they have to login.
In this specific case is not accettable that users "leave" multistep form before the last step, so no redirection to user/login is possible.
What I've done is to try to replicate the login form inside the multistep form and on submit to dynamically login user.
if(isset($form_state['values']['step_4']['user'])){
$uname = $form_state['values']['step_4']['user'];
}
if(isset($form_state['values']['step_4']['password'])){
$password = $form_state['values']['step_4']['password'];
}
if (($uname != '') && ($password != '')) {
if($uid = user_authenticate($uname, $password)) {
global $user;
$user = user_load($uid);
$arr = array ('name'=>$uname,'pass'=>$password);
user_login_finalize($arr);
}
else form_set_error('step_4', t('Wrong Username'));
}
This code works, and user is logged-in, but there are 2 big problems that I can't fix and suppose that aren't fixable:
1.After login, step4 is loaded with an error message that says "form session expired", probably because user is "changed". I'm pretty new to Drupal so I really don't know how to handle this.
2.User menu, logically is not updated, and I can't find documentation on how to dynamically "refresh" it.
Any help is really appreciated.
See the full original question further down
Using the latest Facebook PHP SDK 4.4.0, in my main app page I can do the following to get a user id etc.
<?php
FacebookSession::setDefaultApplication(APP_ID, SECRET);
$helper = new FacebookRedirectLoginHelper( PAGE_URL );
$pageHelper = new FacebookPageTabHelper();
$session = $pageHelper->getSession();
echo '<p>You are currently viewing page: '. $pageHelper->getPageId() . '</p>';
// get user_id
echo '<p>User Id: ' . $pageHelper->getUserId() . '</p>';
// **depcrecated** get like status - use for likegates
echo '<p>You have '. ( $pageHelper->isLiked() ? 'LIKED' : 'NOT liked' ) . ' this page</p>';
// get admin status
echo '<p>You are '. ( $pageHelper->isAdmin() ? 'an ADMIN' : 'NOT an ADMIN' ) . '</p>';
?>
This does not work on sub pages of my app ... Why is the session (and amongst other things, the signed request) lost? How can I get them back and how can I get methods such as getUserId() from the the FacebookPageTabHelper to continue to work on sub pages?
full original question
I'm fairly new to Facebook app development and I'm having problems with session management and I just can't seem to be able to wrap my head around it. Of course it doesn't help that the official documentation is almost useless.
My problem is that the page session get lost when moving away from the apps main page to a subpage within the Facebook page tab app iframe.
I use the following PHP code to obtain the session and user id on the main (initial) app page and it works great:
<?php
FacebookSession::setDefaultApplication(APP_ID, SECRET);
$helper = new FacebookRedirectLoginHelper( PAGE_URL );
$pageHelper = new FacebookPageTabHelper();
$session = $pageHelper->getSession();
?>
But it doesn't work on sub pages :( when a user clicks on a menu item (or any other link inside the app/iframe), the session goes bye bye. Which is not ideal as I need the user id of the user to track whether or not that user has completed certain actions. Of course I could send the ID along with every request, but there must be a way to have a persisting session, no?
Is there a way to retrieve the session on a sub page in PHP? If so, how? Or do I have to load additional content using javascript? And how would that work, if I can't keep the session between requests and therefore have no way of identifying which user a request came from? How do others handle this?
What I'd like to avoid is to write my own user session management, which would solve the problem but is simply not in the budget and I was hoping I could work with what Facebook already had on offer. Especially since my app doesn't require user information/permissions of any kind.
Thanks a lot in advance for any info on this topic, greatly appreciated, going in circles here.
Edit to clarify: I thought of just saving the Facebook session in a PHP session cookie, but how would I use that to reconnect with Facebook after changing the page?
I finally managed to solve this problem. I'm not sure whether this is considered the right way or can even be a recommended way of doing this, but it works and since time is of the essence, I don't have much of a choice.
If anybody has any further ideas or suggestions, please comment.
Here's how I did it:
// store the signed request
if(isset($_REQUEST['signed_request'])) {
$_SESSION['signed_request'] = $_REQUEST['signed_request'];
} elseif($_SESSION['signed_request']) {
$_REQUEST['signed_request'] = $_GET['signed_request'] = $_POST['signed_request'] = $_SESSION['signed_request'];
}
// assign the stored signed request to REQUEST, GET and POST vars (the unsavory bit, imo)
$_REQUEST['signed_request'] = $_GET['signed_request'] = $_POST['signed_request'] = $_SESSION['signedRequest'];
FacebookSession::setDefaultApplication(APP_ID, APP_SECRET);
$accessToken = APP_ID . '|' . APP_SECRET;
$this->session = new FacebookSession($accessToken);
$pageHelper = new FacebookPageTabHelper();
$isAdmin = ($this->pageHelper->getPageData('admin')) ? $this->pageHelper->getPageData('admin') : 0;
// get pade id
echo '<p>You are currently viewing page: '. $pageHelper->getPageId() . '</p>';
// get user_id
echo '<p>User Id: ' . $pageHelper->getUserId() . '</p>';
// get admin status
echo '<p>You are '. ( $isAdmin ? 'an ADMIN' : 'NOT an ADMIN' ) . '</p>';
I want to display just students in moodle users page without manually adding a filter using the web interface. Could anybody help me on how to do?
You can create a link that shows only students but you'll need to post the data. Here's how I did it.
If you install WebDeveloper - http://chrispederick.com/work/web-developer/
Then go to /admin/user.php and click WebDeveloper, choose the "Forms" tab and "convert POSTS to GETS".
Choose the filter and click add filter. This will display a url with all the form fields. Moodle is expecting a POST rather than a GET though.
So copy and paste the url into a variable and use the single_button function with the post method eg:
$url = '/admin/user.php?sesskey=xxxxxxx&_qf__user_add_filter_form=1&mform_showmore_id_newfilter=1&mform_isexpanded_id_newfilter=1&realname_op=0&realname=&lastname_op=0&lastname=&firstname_op=0&firstname=&email_op=0&email=&city_op=0&city=&country_op=0&confirmed=&suspended=&profile_fld=0&profile_op=0&profile=&courserole_rl=5&courserole_ct=0&courserole=&systemrole=0&cohort_op=2&cohort=&username_op=0&username=&auth=&deleted=&addfilter=Add+filter';
echo $OUTPUT->single_button($url, get_string('student'), 'post');
Copy and paste your own url rather than the above.
You can probably remove a lot of the parameters. You should also get the roleid for the student and use the moodle_url function, eg:
$studentroleid = $DB->get_field('role', 'id', array('shortname' => 'student'));
$params = array('courserole_rl' => $studentroleid, 'courserole_ct' => 0, ... );
$url = new moodle_url('/admin/user.php', $params);
echo $OUTPUT->single_button($url, get_string('students'), 'post');
This is not possible, as, in Moodle, it is rare for someone to be assigned the role of 'student' at the system level (and if you did, they would have access to every course on the site).
The concept of 'student' in Moodle only makes sense at the course level.
I'd like to integrate the "like" button into my site, but I cannot make sense of the information available on the web. I read this article, which was in another stackoverflow article, but have some questions: http://www.saschakimmel.com/2010/05/how-to-capture-clicks-on-the-facebook-like-button/. I've also posted this question before and the answers I received really had nothing to do with what I was asking. My original question was asked here: Facebook Integration into website.
I've setup a "Page" already in facebook, and from what I understand in the link above, you need to setup an "App" to get an API key. What I don't understand though is that if I use this API Key, it's going to be pointing to my newly created "App", which has no fan base. How do I link this API Key, (or setup another key through the page admin), so I can have users "like" the real facebook page?
I want to run some javascript functions the moment a user likes the page, but I'm also a little confused on what API functions call, and whether these return a true/false value? I only really want to run these js functions if the user has not already liked the page..
Hope this all makes sense, would love any explanations you have to offer to point me in the right direction.
From what I can see, the answers on your other question cover most of what you need to know. The one thing I notice is your comment:
"I am attempting to set a promo code in the background when someone
"likes" the page"
There are some tricky terms and conditions surrounding this. Have a look here before continuing: https://developers.facebook.com/docs/guides/policy/examples_and_explanations/Rewarding_Users/
If you start off with adding the like button, then separately you will need to check each logged in facebook user to see if they are connected with your page. You can do this using the api call to get their likes, and checking for your page id in the response:
FB.api('/me/likes', function(response) {
console.log(response);
});
If you find a match, proceed with your promotion, else show the like button.
What you're trying to do is totally possible, although I usually do that calculation server-side. You may be able to do it via the Javascript SDK, using the basic concept below. Check out this link: http://fbmhell.com/2011/06/facebook-like-gating-in-iframe-tabs/
The basic overview is this:
You create a Page
You create an app for your promo tab
You add the app tab to your page
When the user hits your app tab on your page, Facebook will return a signed request to you.
You can parse out that signed request using a function like this:
function grokSignedRequest() {
if (isset($_REQUEST['signed_request'])) {
$encoded_sig = null;
$payload = null;
list($encoded_sig, $payload) = explode('.', $_REQUEST['signed_request'], 2);
$sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
$data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
return $data;
}
return false;
}
As mentioned in that article, if you do a print_r() on that signed request after it's been run through the function provided, you’ll see something like this:
stdClass Object
(
[algorithm] => HMAC-SHA256
[issued_at] => 1307627872
[page] => stdClass Object
(
[id] => 116633947708
[liked] => 1
[admin] => 1
)
[user] => stdClass Object
(
[country] => us
[locale] => en_US
[age] => stdClass Object
(
[min] => 21
)
)
)
From there, you can access the liked parameter, and display content based on whether or not the user has liked the page.
// call the function to parse the signed request
$sr_data = grokSignedRequest();
// check like status
if ($sr_data->page->liked==1) {
echo 'you are a fan';
} else {
echo 'you are not a fan.';
}
// check admin status
if ($sr_data->page->admin==1) {
echo '<li>Dude, you are an ADMIN! BADASS!';
}
I have an email address and want to find out if there is a Facebook user linked to this address. If there is, then I want to retrieve the url to this users profile page and save it somewhere.
I do not have a facebook application, but, if necessary, I would use existing account data to login to facebook and perform the task.
I thought this would be an easy task, but somehow it's not. I read through the Graph API documentation and there you find instructions on how to search public data. It says the format is:
https://graph.facebook.com/search?q=QUERY&type=OBJECT_TYPE
But trying this with an email address in the q param and user in the type param without further information results in an OAuthException saying "An access token is required to request this resource."
However, if you click the example search links Facebook generates a url with the mentioned access token related to the currently logged on user. Performing searches with this token gives the expected results. But i cannot figure out how to get this user session access token after logging in. Every time I search on how to get an access token I only find information regarding Facebook apps and retrieving permissions for basic or specific data access. This is, as I mentioned, not what I am looking for, as I don't have and don't need a facebook app.
Since Facebook gives me the needed token in the example links I thought it shouldn't be a problem to get it too. Or do they only have it because of home advantage?
Also, the Outlook Social Connector Provider for Facebook is able to retrieve Facebook data just via an email address (and the account data provided). So I thought, if Microsoft can do this stuff I should be also possible to do simliar things.
Last but not least this is the more frustrating since I, theoretically and practically, am already able to find users profile url just by searching for the email address. I don't even have to be logged on to Facebook. And it's not the official API way.
If I perform a web request to http://www.facebook.com/search.php?init=s:email&q=example#domain.com&type=users I get the expected search result. The problem is that I have to parse the HTML code and extract the url (that's okay) and that the result page is possibly subject to change and could easily break my method to extract the url (problematic).
So does anybody has an idea what's the best way to accomplish the given task?
The definitive answer to this is from Facebook themselves. In post today at https://developers.facebook.com/bugs/335452696581712 a Facebook dev says
The ability to pass in an e-mail address into the "user" search type was
removed on July 10, 2013. This search type only returns results that match
a user's name (including alternate name).
So, alas, the simple answer is you can no longer search for users by their email address. This sucks, but that's Facebook's new rules.
Simply use the graph API with this url format:
https://graph.facebook.com/search?q=zuck#fb.com&type=user&access_token=... You can easily create an application here and grab an access token for it here. I believe you get an estimated 600 requests per 600 seconds, although this isn't documented.
If you are doing this in bulk, you could use batch requests in batches of 20 email addresses. This may help with rate limits (I am not sure if you get 600 batch requests per 600 seconds or 600 individual requests).
In response to the bug filed here: http://developers.facebook.com/bugs/167188686695750 a Facebook engineer replied:
This is by design, searching for users is intended to be a user to user function only, for use in finding new friends or searching by email to find existing contacts on Facebook. The "scraping" mentioned on StackOverflow is specifically against our Terms of Service https://www.facebook.com/terms.php and in fact the only legitimate way to search for users on Facebook is when you are a user.
Maybe this is a little bit late but I found a web site which gives social media account details by know email addreess. It is https://www.fullcontact.com
You can use Person Api there and get the info.
This is a type of get : https://api.fullcontact.com/v2/person.xml?email=someone#****&apiKey=********
Also there is xml or json choice.
I've captured the communication of Outlook plugin for Facebook and here is the POST request
https://api.facebook.com/method/fql.multiquery
access_token=TOKEN&queries={"USER0":"select '0', uid, name, birthday_date, profile_url, pic, website from user where uid in (select uid from email where email in ('EMAIL_HASH'))","PENDING_OUT":"select uid_to from friend_request where uid_from = MY_ID and (uid_to IN (select uid from #USER0))"}
where
TOKEN - valid access token
EMAIL_HASH - combination of CRC32 and MD5 hash of searched email address in format crc32_md5
MY_ID - ID of facebook profile of access token owner
But when I run this query with different access token (generated for my own application) the server response is: "The table you requested does not exist" I also haven't found the table email in Facebook API documentation. Does Microsoft have some extra rights at Facebook?
Andreas,
I've also been looking for an "email-to-id" ellegant solution and couldn't find one.
However, as you said, screen scraping is not such a bad idea in this case, because emails are unique and you either get a single match or none. As long as Facebook don't change their search page drastically, the following will do the trick:
final static String USER_SEARCH_QUERY = "http://www.facebook.com/search.php?init=s:email&q=%s&type=users";
final static String USER_URL_PREFIX = "http://www.facebook.com/profile.php?id=";
public static String emailToID(String email)
{
try
{
String html = getHTML(String.format(USER_SEARCH_QUERY, email));
if (html != null)
{
int i = html.indexOf(USER_URL_PREFIX) + USER_URL_PREFIX.length();
if (i > 0)
{
StringBuilder sb = new StringBuilder();
char c;
while (Character.isDigit(c = html.charAt(i++)))
sb.append(c);
if (sb.length() > 0)
return sb.toString();
}
}
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private static String getHTML(String htmlUrl) throws MalformedURLException, IOException
{
StringBuilder response = new StringBuilder();
URL url = new URL(htmlUrl);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
{
BufferedReader input = new BufferedReader(new InputStreamReader(httpConn.getInputStream()), 8192);
String strLine = null;
while ((strLine = input.readLine()) != null)
response.append(strLine);
input.close();
}
return (response.length() == 0) ? null : response.toString();
}
This is appeared as pretty easy task, as Facebook don't hiding user emails or phones from me. So here is html parsing function on PHP with cURL
/*
Search Facebook without authorization
Query
user name, e-mail, phone, page etc
Types of search
all, people, pages, places, groups, apps, events
Result
Array with facebook page names ( facebook.com/{page} )
By 57ar7up
Date 2016
*/
function facebook_search($query, $type = 'all'){
$url = 'http://www.facebook.com/search/'.$type.'/?q='.$query;
$user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36';
$c = curl_init();
curl_setopt_array($c, array(
CURLOPT_URL => $url,
CURLOPT_USERAGENT => $user_agent,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE
));
$data = curl_exec($c);
preg_match_all('/href=\"https:\/\/www.facebook.com\/(([^\"\/]+)|people\/([^\"]+\/\d+))[\/]?\"/', $data, $matches);
if($matches[3][0] != FALSE){ // facebook.com/people/name/id
$pages = array_map(function($el){
return explode('/', $el)[0];
}, $matches[3]);
} else // facebook.com/name
$pages = $matches[2];
return array_filter(array_unique($pages)); // Removing duplicates and empty values
}
Facebook has a strict policy on sharing only the content which a profile makes public to the end user.. Still what you want is possible if the user has actually left the email id open to public domain..
A wild try u can do is send batch requests for the maximum possible batch size to ids..."http://graph.facebook.com/ .. and parse the result to check if email exists and if it does then it matches to the one you want.. you don't need any access_token for the public information ..
in case you want email id of a FB user only possible way is that they authorize ur app and then you can use the access_token thus generated for the required task.
Maybe things changed, but I recall rapleaf had a service where you enter an email address and you could receive a facebook id.
https://www.rapleaf.com/
If something was not in there, one could "sign up" with the email, and it should have a chance to get the data after a while.
I came across this when using a search tool called Maltego a few years back.
The app uses many types of "transforms", and a few where related to facebook and twitter etc..
..or find some new sqli's on fb and fb apps, hehe. :)
WARNING: Old and outdated answer. Do not use
I think that you will have to go for your last solution, scraping the result page of the search, because you can only search by email with the API into those users that have authorized your APP (and you will need one because the token that FB provides in the examples has an expiry date and you need extended permissions to access the user's email).
The only approach that I have not tried, but I think it's limited in the same way, is FQL. Something like
SELECT * FROM user WHERE email 'your#email.com'
First I thank you. # 57ar7up and I will add the following code it helps in finding the return phone number.
function index(){
// $keyword = "0946664869";
$sql = "SELECT * FROM phone_find LIMIT 10";
$result = $this->GlobalMD->query_global($sql);
$fb = array();
foreach($result as $value){
$keyword = $value['phone'];
$fb[] = $this->facebook_search($keyword);
}
var_dump($fb);
}
function facebook_search($query, $type = 'all'){
$url = 'http://www.facebook.com/search/'.$type.'/?q='.$query;
$user_agent = $this->loaduserAgent();
$c = curl_init();
curl_setopt_array($c, array(
CURLOPT_URL => $url,
CURLOPT_USERAGENT => $user_agent,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE
));
$data = curl_exec($c);
preg_match('/\{"id":(?P<fbUserId>\d+)\,/', $data, $matches);
if(isset($matches["fbUserId"]) && $matches["fbUserId"] != ""){
$fbUserId = $matches["fbUserId"];
$params = array($query,$fbUserId);
}else{
$fbUserId = "";
$params = array($query,$fbUserId);
}
return $params;
}