How to Do Facebook Login Using 'wp_insert_user'? - json

I am building a user generated content sharing theme and I want to make a custom Facebook connect. After researching, I found out this code.
The following code is adding the app to the users profile in Facebook, but is not creating a new user and also doesn't makes them logged in.
Here is the full code (to be added in functions.php).
Step 1 - Intializing javascript at header area
function fb_head(){
if( is_user_logged_in() )
return;
?>
<script type="text/javascript">
window.fbAsyncInit = function(){
FB.init({
appId:'APP_ID',
status:true,
cookie:true,
xfbml:true,
oauth:true
});
};
</script>
<div id="fb-root"></div>
<script type="text/javascript">
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
</script>
<?php
}
add_action( 'wp_head', 'fb_head' );
Step 2 - Inserting a button for facebook login
<button id="facebook_connect">Connect with facebook</button>
Step 3 - Loading Jquery Library
function mytheme_enqueue_scripts(){
wp_enqueue_script( 'jquery' );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts');
Step 4 - Add a jQuery on-click function to the button we have created
This code will be placed on the wp footer section (before the closing body tag).
function fb_footer(){
if( is_user_logged_in()):
echo "<script type='text/javascript'> jQuery('#facebook_connect').hide(); </script>";
return;
endif;
?>
<script type="text/javascript">
jQuery('#facebook_connect').click(function(){
FB.login(function(FB_response){
if( FB_response.status === 'connected' ){
fb_intialize(FB_response);
}
},
{scope: 'email'});
});
function fb_intialize(FB_response){
FB.api(
'/me',
'GET',
{'fields':'id,email,username,verified,name'},
function(FB_userdata){
jQuery.ajax({
type: 'POST',
url: 'AJAXURL',
data: {
"action": "fb_intialize",
"FB_userdata": FB_userdata,
"FB_response": FB_response
},
success: function(user){
if( user.error ){
alert( user.error );
}
else if( user.loggedin ){
window.location.reload();
}
}
});
}
);
};
</script>
<?php
}
add_action( 'wp_footer', 'fb_footer' );
Step 5 - MAIN STEP: Adding the handler function
function wp_ajax_fb_intialize(){
#error_reporting( 0 ); // Don't break the JSON result
header( 'Content-type: application/json' );
if( !isset( $_REQUEST['FB_response'] ) || !isset( $_REQUEST['FB_userdata'] ))
die( json_encode( array( 'error' => 'Authonication required.' )));
$FB_response = $_REQUEST['FB_response'];
$FB_userdata = $_REQUEST['FB_userdata'];
$FB_userid = (int) $FB_userdata['id'];
if( !$FB_userid )
die( json_encode( array( 'error' => 'Please connect your facebook account.' )));
global $wpdb;
$user_ID = $wpdb->get_var( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '_fbid' AND meta_value = '$FB_userid'" );
if( !$user_ID ){
$user_email = $FB_userdata['email'];
$user_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->users WHERE user_email = '$user_email'" );
if( !$user_ID ){
if ( !get_option( 'users_can_register' ))
die( json_encode( array( 'error' => 'Registration is not open at this time. Please come back later..' )));
extract( $FB_userdata );
$display_name = $name;
$user_login = $username;
if( empty( $verified ) || !$verified )
die( json_encode( array( 'error' => 'Your facebook account is not verified. You hae to verify your account before proceed login or registering on this site.' )));
$user_email = $email;
if ( empty( $user_email ))
die( json_encode( array( 'error' => 'Please re-connect your facebook account as we couldnt find your email address..' )));
if( empty( $name ))
die( json_encode( array( 'error' => 'empty_name', 'We didnt find your name. Please complete your facebook account before proceeding..' )));
if( empty( $user_login ))
$user_login = sanitize_title_with_dashes( sanitize_user( $display_name, true ));
if ( username_exists( $user_login ))
$user_login = $user_login. time();
$user_pass = wp_generate_password( 12, false );
$userdata = compact( 'user_login', 'user_email', 'user_pass', 'display_name' );
$user_ID = wp_insert_user( $userdata );
if ( is_wp_error( $user_ID ))
die( json_encode( array( 'error' => $user_ID->get_error_message())));
update_user_meta( $user_ID, '_fbid', (int) $id );
}
else{
update_user_meta( $user_ID, '_fbid', (int) $FB_userdata['id'] );
}
}
wp_set_auth_cookie( $user_ID, false, false );
die( json_encode( array( 'loggedin' => true )));
}
add_action( 'wp_ajax_nopriv_fb_intialize', 'wp_ajax_fb_intialize' );
THis is how I add the Facebook button:
<button id="facebook_connect">Connect with Facebook</button>
If anyone is trying it please replace the App ID.

Thanks for the code! Worked like a charm. But there is one really important security thing I discovered!
In the console I just changed facebook variables before sending the ajax request and I could login with everyones fb account (if you know their facebook id). The next couple of lines also check the fb token and validates if the login really is valid!
So in your wp_ajax_fb_intialize function you should definetely add these couple of lines:
$FB_response = $_REQUEST['FB_response'];
$FB_userdata = $_REQUEST['FB_userdata'];
$FB_userid = (int) $FB_userdata['id'];
//NEW CODE INSERT - check if token is valid
$token = $FB_response['authResponse']['accessToken'];
$path = 'https://graph.facebook.com/me?access_token='.$token;
$content = #file_get_contents($path);
$fb_user = json_decode($content);
if ($fb_user->id != $FB_userdata['id'])
die( json_encode( array( 'error' => 'FB login error' )));
I used file_get_contents but it is also possible to use curl

Changed the ajax url from
url: 'AJAXURL',
to
url: '<?php echo admin_url('admin-ajax.php'); ?>',
One thing I noticed while testing was that if I delete a user from the wp_users table the user meta with the facebook id will still be there so you may need to check if the facebook id is associated with an invalid user id in your ajax callback e.g.
global $wpdb;
$user_ID = $wpdb->get_var( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '_fbid' AND meta_value = '$FB_userid'" );
// check if the user id is valid
if( false === ($check_user = get_userdata($user_ID)) )
{
$user_ID = false; // set to false to force create a new user
}
The rest of your code worked fine.

Related

Custom WordPress New User E-Mail from Template

From a custom function to register users, I inserted this function to generate and overwrite the WordPress system email for new user notification.
function custom_wp_new_user_notification_email( $wp_new_user_notification_email, $user, $blogname ) {
global $wpcargo;
$user_url = stripslashes( $user->user_url );
$user_login = stripslashes( $user->user_login );
$user_email = stripslashes( $user->user_email );
$user_firstname = stripslashes( $user->user_firstname );
$user_last_name = stripslashes( $user->user_last_name );
$user_pass = stripslashes( $user->user_pass );
$message = file_get_contents('../email/mail-template.php');
$wp_new_user_notification_email['subject'] = sprintf( '[%s] Welcome.', $blogname );
$wp_new_user_notification_email['headers'] = array('Content-Type: text/html; charset=UTF-8');
$wp_new_user_notification_email['message'] = $message;
return $wp_new_user_notification_email;
}
add_filter( 'wp_new_user_notification_email', 'custom_wp_new_user_notification_email', 10, 3 );
Emails are being sent but I cannot get user data printed in the PHP / HTML file.
<p style="margin-top:0;margin-bottom:12px;"><b>Name</b>: <?php $user_firstname; ?></p>
I'm wrong with the code, any suggestions?
I would use locate_template for the email contents and output buffering rather than file_get_contents - also as #Zak pointed out, you have to echo your output otherwise it won't show up.
function custom_wp_new_user_notification_email( $wp_new_user_notification_email, $user, $blogname ) {
global $wpcargo;
$user_url = stripslashes( $user->user_url );
$user_login = stripslashes( $user->user_login );
$user_email = stripslashes( $user->user_email );
$user_firstname = stripslashes( $user->user_firstname );
$user_last_name = stripslashes( $user->user_last_name );
$user_pass = stripslashes( $user->user_pass );
ob_start();
include( locate_template( '/email/mail-template.php' ); // This path may vary depending on your setup.
$wp_new_user_notification_email['message'] = ob_get_clean();
$wp_new_user_notification_email['subject'] = sprintf( '[%s] Welcome.', $blogname );
$wp_new_user_notification_email['headers'] = array('Content-Type: text/html; charset=UTF-8');
return $wp_new_user_notification_email;
}
add_filter( 'wp_new_user_notification_email', 'custom_wp_new_user_notification_email', 10, 3 );
Within your template you want to make sure you echo and esc_html() for anything that is being outputted.
<?php echo esc_html( $user_firstname ); ?>

Use the loop to check if DB record exists in WordPress?

I have a somewhat unorthodox (i guess) question. I have a function that adds a record to my MYSQL DB, with location lat and lng info. However sometimes that function is not working correctly, causing for the the DB record not to be created. Therefore I would like to create a loop to keep checking if the function created the DB record and if not, do the function again.
Just to be clear; the function I use is a default GEOMyWP function (reference). Sometimes it is not working properly, I guess due to the Google maps API response time.
I have the following in my functions.php and it seems to be working. I really would like to know if this is a proper way to accomplish the above, since I am not sure. Thanks
global $wpdb;
$myccount = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM ".$wpdb->prefix."gmw_locations WHERE object_id = %d", $post_id));
if ($myccount <= 0) :
while ($myccount <= 0) :
gmw_pt_update_location( $args ); //The function I would like to check.
$myccount = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM ".$wpdb->prefix."gmw_locations WHERE object_id = %d", $post_id));
endwhile;
endif;
Below is the function that i use to import the address, when creating a post for a CPT
function gmw_update_post_type_post_location( $post_id ) {
// Return if it's a post revision
if ( false !== wp_is_post_revision( $post_id ) )
return;
// check autosave //
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
//check if user can edit post
if ( !current_user_can( 'edit_post', $post_id ) )
return;
//Add post Meta
add_post_meta($post_id, 'address', $_POST['address'], false);
//get the address from the custom field "address"
$addressarray = get_post_meta( $post_id, 'address', true );
$address = $addressarray[0];
//$address = $_POST['address'];
//varify that address exists. Otherwise abort the function.
if ( empty( $address ) )
return;
//include the update location file file
include_once( GMW_PT_PATH .'/includes/gmw-pt-update-location.php' );
//make sure the file included and the function exists
if ( !function_exists( 'gmw_pt_update_location' ) )
return;
//Create the array that will pass to the function
$args = array(
'post_id' => $post_id, //Post Id of the post
'address' => $address // the address we pull from the custom field above
);
//Start counting 1
global $wpdb;
$myccount = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM ".$wpdb->prefix."gmw_locations WHERE object_id = %d", $post_id));
if ($myccount <= 0) :
while ($myccount <= 0) :
//Add location
gmw_pt_update_location( $args );
//Start counting 2
$myccount = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM ".$wpdb->prefix."gmw_locations WHERE object_id = %d", $post_id));
endwhile;
endif;
}
//execute the function whenever post type is being updated
add_action( 'save_post_mpp-gallery', 'gmw_update_post_type_post_location', 13, 1 );
Function that is inserting a record to the db is eventually: gmw_update_location
This function can be found in the GEOMyWP plugin. See this link for some reference: https://github.com/Fitoussi/geo-my-wp/blob/master/includes/gmw-location-functions.php#LC194

How to make a json from youtube api v3 with a wp_cron

I'm doing a cron job in wordpress and it only worked once, it sent me an email but it never created the json file.
I want to save in a json file data from youtube api v3 in order not make petitions each time because youtube limit the petitions so I thought it will be convenient make a cache job with wp cron but this code is not working. I not sure where is the problem.
function isa_add_every_three_minutes( $schedules ) {
$schedules['every_three_minutes'] = array(
'interval' => 180,
'display' => __( 'Every 3 Minutes', 'textdomain' )
);
return $schedules;
}
add_filter( 'cron_schedules', 'isa_add_every_three_minutes' );
if ( !wp_next_scheduled('hook_saveVideos') ) {
wp_schedule_event( time(), 'every_three_minutes', 'hook_saveVideos' );
}
function saveVideos() {
$channel_id = "channelExample";
$user_id = "example";
$url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=30&playlistId=".$cv_id."&key=".$user_id;
$data = file_get_contents($url);
$videos = json_decode($data, true);
$videos = $videos['items'];
$dVideos = array();
for ($i=0; $i < count($videos) ; $i++) {
$title = $videos[$i]['snippet']['title'];
$description = $videos[$i]['snippet']['description'];
$videoId = $videos[$i]['snippet']['resourceId']['videoId'];
$id = "v".$i;
$dVideos[$id] = array("title"=>$title, "description"=>$description, "videoId"=>$videoId);
}
$ruta = "http://localhost/example/cache";
$fp = fopen($ruta, 'w');
fwrite($fp, json_encode($dVideos ));
fclose($fp);
wp_mail('user#example.com', 'Mail mandado por el cron', 'Hola, esto es un correo enviado automáticamente');
}

codeigniter - convert html to pdf

I have a little problem. I have html page and I want to convert to pdf. My index page has a list that will get to the database and click on "Download PDF", I put this list in a PDF file.
My controller:
<?php
class pdf_c extends CI_Controller{
function __construct() {
parent::__construct();
$this->load->helper(array('url', 'mediatutorialpdf'));
}
function index($download_pdf = ''){
$ret = '';
$ID = 1;
$pdf_filename = 'user_info_'.$ID.'.pdf';
$link_download = ($download_pdf == TRUE)?'':anchor(base_url().'index.php/true', 'Download PDF');
$query = $this->db->query("SELECT * FROM `ci_pdf_user` WHERE `id` = '{$ID}' LIMIT 1");
if($query->num_rows() > 0)
{
$user_info = $query->row_array();
}
$data_header = array(
'title' => 'Convert codeigniter to pdf'
);
$data_userinfo = array(
'user_info' => $user_info,
'link_download' => $link_download
);
$header = $this->load->view('header',$data_header, true);
$user_info = $this->load->view('user_table', $data_userinfo, true);
$footer = $this->load->view('footer','', true);
$output = $header.$user_info.$footer;
if($download_pdf == TRUE)
{
generate_pdf($output, $pdf_filename);
}
else
{
echo $output;
}
}
}
?>
The problem is when I click the button "Download PDF" should redirect me to the function index () and get the $ download_pdf = true. And so called generate_pdf function () that will generate the PDF.
I think the problem is in the variable $ link_download, but can not solve the problem.
Thanks
I think that you could try with:
function index(pdf = 0)...
Then check that optional parameter with:
$pdf = $this->uri->segment(2, 0); //not sure, should be 2? try it...`
And then, if $pdf=='1' (send nummber rather than string 'true') ...etc,etc...

Enable a mediawiki function to render wikitext

My mediawiki version is 1.16.5. I have a function that selects a random quote from the database and displays it on a wiki page. Italics and bold are rendered when I use html, however, I want to be able to use wikitext, specifically external links format, i.e.
[http://mediawiki.org MediaWiki]
Currently, if using something like the above, it is not rendered and displays literally. There is some reference on what is needed here: http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_do_I_render_wikitext_in_my_extension.3F but I do not know how to implement this.
Here is the code:
function wfGetQuote() {
$randstr = wfRandom();
$row = selectRandomQuoteFromDB( $randstr );
if( !$row )
$row = selectRandomQuoteFromDB( "0" );
if( $row ) {
list( $quote, $attribution ) = explode( "\n", $row->quote_text );
return '<div id="trrandomquote"><div id="trquote">'. $quote .'</div> <span>'. $attribution .'</span></div>';
}
else
return 'Error: No quote found';
}
function selectRandomQuoteFromDB( $randstr ) {
global $wgUser, $site;
$lang = $wgUser->getOption( 'language' );
if( $site == 'wiki' )
$lang = 'en';
$dbr = wfGetDB( DB_SLAVE );
$use_index = $dbr->useIndexClause( 'quote_random' );
$quote = $dbr->tableName( 'quote' );
$sql = "SELECT quote_text
FROM $quote $use_index
WHERE quote_random >= $randstr
AND quote_lang = '$lang'";
$sql = $dbr->limitResult( $sql, 1, 0 );
$fname = 'RandomQuote::selectRandomQuoteFromDB';
$res = $dbr->query( $sql, $fname );
return $dbr->fetchObject( $res );
}
Normally I use the $wgOut->addWikiText( $msg ); function.
I would modify your code to:
function wfGetQuote() {
global $wgOut; // Added line
$randstr = wfRandom();
$row = selectRandomQuoteFromDB( $randstr );
if( !$row )
$row = selectRandomQuoteFromDB( "0" );
if( $row ) {
list( $quote, $attribution ) = explode( "\n", $row->quote_text );
$wgOut->addWikiText( '<div id="trrandomquote"><div id="trquote">'. $quote .'</div> <span>'. $attribution .'</span></div>' );
}
else
return 'Error: No quote found';
}
I haven't tested it, but it may do the job you're looking for.