Deleting each notification as a user accepts - facebook-graph-api

How can I make the app delete the notifications as a user accepts them? For example the user sends a request to friends, the users are then notified of this before giving the option to accept or reject. On acceptance I need to enter some info into a database, which isn't the problem I'm having.
I'm using the code below, and the problem i'm finding is when the user has multiple requests from different people. It's either deleting all of the requests or none at all, ideally I need it to delete each request the user has accepted. Any ideas?
$request = $facebook->api("/me/apprequests");
foreach ($request as $data) {
echo "<form method='post'>";
foreach ($data as $full_request_id) {
echo "<input type='submit' name='yes' id='yes' value='Yes'>";
if ((isset($_POST['yes']))) {
try {
$delete_success = $facebook->api("/$full_request_id",'DELETE');
if ($delete_success) {
echo "Successfully deleted " . $full_request_id;}
else {
echo "Delete failed".$full_request_id;}
}
catch (FacebookApiException $e) {
echo $e;}
}
echo "</form>";
}
}

There's sample code on the page for the Requests dialog: https://developers.facebook.com/docs/reference/dialogs/requests/
I believe the recommended workflow is to delete all pending requests for that user (from Facebook's side); if you still need the user to manually accept them one by one after they click the first one, you can render your own interface for the remaining requests
This is what apps like Cityville do - when you click through from a Facebook requests they clear all your Facebook requests and render their own dialog for you to accept the remaining (now hidden from Facebook's onterface) gifts.

Related

Joomla 3.6 Authentication and Login

I' m having a difficulty in getting a clear view on Joomla (I'm using version 3.6.x) authentication and login.
I've seen many approaches and snippets on how to "Login" in a Joomla site from an external source (which is what i m interesting in).
But what i see after testing and testing (and more testing), is that at the end of the day, you re simply not logged in.
You may have the ability to verify that the user who's attempting to login is a valid registered user and also to be able to retrieve his name, email, phone and blah blah blah but in Joomla backend, this user is still not logged in.
I created a brand new user in Administrator Panel (it shows the user NEVER visited the site), I wrote the login script in external PHP, I "authenticated" the new user a dozen times and when i go back to the Backend, the user still NEVER been there. Not even once.
Which, i guess, it also means that i can't retrieve a list of "active" users, since Joomla can't see them as logged in users.
So what i want to achieve is users to be able to login from outside the Joomla site and to have the ability to know IF they're logged in or not. So I can get a list of them and assign tasks to them.
I guess it has something to do with tokens and cookies. But no matter how much i searched to that direction, i can't find any examples to enlighten me.
Any help (and specially "scripting" help) is much appreciated.
Thank you.
<?php
if (version_compare(PHP_VERSION, '5.3.1', '<')) {
die('Your host needs to use PHP 5.3.1 or higher to run this version of Joomla!');
}
define('_JEXEC', 1);
if (file_exists(__DIR__ . '/defines.php')) {
include_once __DIR__ . '/defines.php';
}
if (!defined('_JDEFINES')) {
define('JPATH_BASE', __DIR__);
require_once JPATH_BASE . '/includes/defines.php';
}
require_once JPATH_BASE . '/includes/framework.php';
$app = JFactory::getApplication('site');
$app->initialise();
require_once (JPATH_BASE .'/libraries/joomla/factory.php');
$credentials['username'] = $_GET["usrname"];
$credentials['password'] = $_GET["passwd"];
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('id, password')
->from('#__users')
->where('username=' . $db->quote($credentials['username']));
$db->setQuery($query);
$result = $db->loadObject();
if ($result) {
$match = JUserHelper::verifyPassword($credentials['password'], $result->password, $result->id);
if ($match === true) {
$user = JUser::getInstance($result->id);
$session =& JFactory::getSession();
echo "<p>Your name is {$user->name}, your email is {$user->email}, and your username is {$user->username}</p>";
$session->set('userid', $user->id);
if ($user->guest) {
echo 'SORRY, NO LOGIN YET...';
} else {
echo 'user is LOGGED IN !';
}
} else {
die('Invalid password');
}
} else {
die('Cound not find user in the database');
}
?>
Joomla log in is handled in authentication plugins, by writing and enabling your own you can bypass the token verification and allow logging in by a simple get request.
Keep in mind that Joomla! keeps administrator and frontend sessions separate (you can be logged into the administrator, and browse the site as a guest). Additionally, a user needs a Manager, Administrator or Super User group membership to login to the backend.
Administrator
The common use case for admin login is to run a background script.
In order to bypass the Joomla Authentication in the backend, check out the /cli folder as it contains some examples.
Frontend
The use case for frontend login is much wider: server-to-server communication, app authentication, single sign on etc.
The best practice to perform frontend authentication is to build your own authentication plugin. The authentication will be implemented by the onUserAuthenticate() function. Check out the /plugins/authentication/joomla/ plugin for an example.
If you need extra data for the authentication plugin to perform its magic (e.g. the remote token/api key to authenticate using a remote service) you might want to check out the user plugin group, for example the /plugins/user/profile plugin.
Verify last login date/time
The frontend approach should automatically work, showing users as logged in in the administrator control panel.
However, if you use the CLI approach to login to the administrator, this may not work depending on how you perform login.
To be able to check if a user is logged in only authentication is not enough but you need a forced login. Only then you will be able to view them at the backend.
This is the code you can use to check if a user is logged in or not
<?php
if (version_compare(PHP_VERSION, '5.3.1', '<')) {
die('Your host needs to use PHP 5.3.1 or higher to run this version of Joomla!');
}
if (!ini_get('display_errors')) {
ini_set('display_errors', '1');
}
echo ini_get('display_errors');
define('_JEXEC', 1);
define('JPATH_BASE', "C:\Vertrigo\www\joomla" );//Define the Base path as per your installation directory
if (!defined('_JDEFINES'))
{
require_once JPATH_BASE . '/includes/defines.php';
}
require_once JPATH_BASE . '/includes/framework.php';
// Instantiate the application.
$app = JFactory::getApplication('site');
$app->initialise();
require_once (JPATH_BASE .'/libraries/joomla/factory.php');
//Check if a user exists else create one with forced login
$user = JFactory::getUser();
jimport('joomla.plugin.helper');
$credentials = array();
$credentials['username'] = JRequest::getVar('username', '');
$credentials['password'] = JRequest::getVar('passwd', '');
if (!$user->get('gid')){
$forcevars = array();
$forcevars['silent'] = true;
$forcevars['forecelogon'] = true;
$response = $app->login($credentials, $forcevars);
if($response){
echo "Login Successful";
}else{
echo "Login Unsuccessful. Check Username and Password. Give just Plain password.";
}
}
?>
I have modified the code as you neeeded to call username and password in url. better to use getVar in joomla rather than GET method. You url will be in the format http://www.yoursite.com/thisscript.php?username=yourusername&passwd=yourpassword

Setting user's email on Facebook signup with Parse.com

I'm using Parse.com and trying to set up user sign up with Facebook.
Upon authentication with Facebook for the first time a beforeSave is called on _User to fetch additional user details:
function UserBeforeSave(request, response){
var user = request.object,
auth = user.get('authData');
// check if user is newly registered
if (!user.existed()) {
// Check if a user signs up with facebook
if (Parse.FacebookUtils.isLinked(request.object)) {
// Query Graph API for user details
Parse.Cloud.httpRequest({
url:'https://graph.facebook.com/v2.2/me?access_token=' + auth.facebook.access_token,
success:function(httpResponse){
// Map facebook data to user object
if (httpResponse.data.first_name) request.object.set('first_name', httpResponse.data.first_name);
if (httpResponse.data.last_name) request.object.set('last_name', httpResponse.data.last_name);
if (httpResponse.data.email) request.object.set('email', httpResponse.data.email);
response.success();
},
error:function(httpResponse){
console.error(httpResponse);
response.error();
}
});
} else {
response.success();
}
} else {
response.success();
}
}
Problem is that that email line is actually breaking the operation with error:
Can't modify email in the before save trigger
I tried moving this code to the afterSave but the authdata is not available there making it difficult to call the FB API. The email is therefore left blank at the moment.
I'm assuming this is a very common use case of integrating Parse with the Facebook API, am I missing something in the integration process that automatically fetches the email?
I just do the graph query client-side and set email there. This works fine.
Is there a reason you want to do it in the before/afterSave on the User?

Facebook PHP SDK 4.0 - Cannot re-ask read permissions once denied

I'm currently asking users for two read permissions i.e. email and user_location and one write permssion i.e. publish_actions. Following is the code snippet I'm using to verify if the user has granted all requested permissions:
$facebook = new Facebook(APP_ID, APP_SECRET, REDIRECT_URI);
if ( $facebook->IsAuthenticated() ) {
// Verify if all of the scopes have been granted
if ( !$facebook->verifyScopes( unserialize(SCOPES) ) ) {
header( "Location: " . $facebook->getLoginURL( $facebook->denied_scopes) );
exit;
}
...
}
Facebook is a class I've customly built to wrap the login flow used by various classes in the SDK. IsAuthenticated() makes the use of code get variable to check if the user is authorized. verifyScopes() checks granted permissions against SCOPES and assings an array of denied scopes to denied_scopes property. getLoginURL()` builds a login-dialog URL based on permissions passed as an an array as a only paramter.
Now, the problem is when the user doesn't grant write permissions, publish_actions in this case, write permission dialog is shown until user grants the write permission. But if the user chooses to deny of the read permissions, say email, the read login dialog isn't show. Instead Facebook redirects to the callback URL (that is REDIRECT_URI) creating a redirect loop.
The application I'm builiding requires email to be compulsorily provided but apparently the above approach (which seems to be the only) is failing. So, is there a workaround or a alternative way to achieve this? Or Facebook doesn't allow to ask for read permissions once denied?
As of July 15, 2014, an update has been made to the Facebook PHP SDK 4.x that allows user to re-ask the declined permissions. The function prototype of getLoginUrl() now looks like this.
public function getLoginUrl($redirectUrl, $scope = array(), $rerequest = false, $version = null)
So, to re-ask declined permissions we'd do something like this:
<?php
// ...
$helper = new FacebookRedirectLoginHelper();
if ($PermissionIsDeclined) {
header("Location: " . $helper->getLoginUrl( $redirect_uri, $scopes, true );
exit;
}
// ....
?>
For the time being you can append &auth_type=rerequest to the getLoginUrl return value to enable a rerequest, kind of lame but it works.
$helper = new FacebookRedirectLoginHelper($app_url, $app_id, $app_secret);
$login = $helper->getLoginUrl(array('scope'=>'user_likes', 'user_location'));
print $login."&auth_type=rerequest";
what about getReRequestUrl(); ?
That works just fine.
Read more at https://developers.facebook.com/docs/php/FacebookRedirectLoginHelper/5.0.0

Facebook realtime updates, no post update from facebook

I followed the guide realtime updates on facebook.
My application is a tab page.
I'm using the sandbox environment.
Initially set up by the signing of the dashboard.
The callback URL endpoint verify works fine.
I did an post on the page for only test.
But so far (after 24hrs), i received no update post from facebook.
On log apache server, there is no post from facebook too.
My callback script:
<?php
define('UPD_FILE', 'updates.log');
$method = $_SERVER['REQUEST_METHOD'];
global $log_file;
if ($method == 'GET' && $_GET['hub_mode'] == 'subscribe' && $_GET['hub_verify_token'] == 'jogabonito') {
echo $_GET['hub_challenge'];
exit;
}
else if ($method == 'POST')
{
$log_file=UPD_FILE;
$updates = json_decode(file_get_contents("php://input"), true);
logToFile("updates =".print_r($updates));
}
function logToFile($message){
global $log_file;
$hdl = fopen($log_file, 'a') or die ("couldn't open log file");
fwrite($hdl,$message."\n");
fclose($hdl);
}
?>
Grateful for the attention
Your code works (somewhat) fine after some requirements have been met.
You have subscribed successfully for at least one field change.
The user you are testing with has granted your app some or all of the required permissions for the fields you are subscribed for.
If one of the above isn't properly handled you won't be notified about related changes.
On another note I wrote "somewhat" because you are dumping the array content using print_r without specifying that the function should return the data rather than print it. The way you have it right now will result in a "1" result.
What you need should look more like this:
logToFile("updates =".print_r($updates, true));
I was facing the same problem, below solution fixed my problem,
just make an POST request to the following URL
https://graph.facebook.com/PAGE_ID/tabs?app_id=APP_ID&access_token=PAGE_ACCESS_TOKEN
Please replace the values before making a request

How do you specify the requester's workerID in a mechanical turk HIT?

I want to create an mturk HIT that has a URL like so:
www.example.com?source=worker_id
where worker_id is the worker's ID code. I'm initially going to create these from the mturk web UI, then once I get it working right, from PHP. But I can't figure out how to get at the worker's ID from the modified-HTML syntax of an mturk HIT.
Mechanical Turk will call your website with a URL that looks like:
www.example.com/?hitId=2384239&assignmentId=ASD98ASDFADJKH&workerId=ASDFASD8
In your php page that is at that location you can access the workerId (as well as the other Ids) like so:
<?php
$hitId = $_REQUEST["hitId"];
$assignmentId = $_REQUEST["assignmentId"];
$workerId = $_REQUEST["workerId"];
echo "Hit ID: $hitId\n";
echo "Ass ID: $assignmentId\n";
echo "Worker ID: $workerId\n";
?>
Note that the workerId is NOT sent during the preview, only after the HIT has been accepted. If you're using an External HIT, you can create a cookie to see if it's a worker who has accepted a previous hit, but of course that method is unreliable.