Last active
November 21, 2019 21:34
-
-
Save palpalani/6432885 to your computer and use it in GitHub Desktop.
PliggConnect for WordPress Integrating Pligg with WordPress
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
I've managed to get Pligg to use WordPress authentication and user database. | |
I recently got Pligg using Pubcookie and that formed the basis of this work, however they are very different. | |
I've only tested this with Pligg. I believe future versions may have a better approach for external authentication so I can't guarantee this will work with future versions. | |
This approach is very "hacky". I've also been slightly lazy. It assumes that you will use WordPress' login, logout and register pages. This will break the existing login, logout and register forms in Pligg. The ultimate solution would allow the Pligg forms to login and logout also on WordPress and the register form to create new users in WordPress. | |
It also does not attempt to merge the user databases from WordPress and Pligg together. Instead they are left seperate. This means that administrators have two places to manage users. If you want to delete a user, you've got to delete them from WordPress and Pligg seperately. | |
I've done previous external application integrations with WordPress, most notable with DokuWiki. In these previous case, I was able to allow the use of WordPress template tags in DokuWiki. However, in the case of Pligg, it is not possible as there are several function name clashes. Pligg and WordPress are considered CMSs (Content Management Systems) and it is inevitable that function names and variables clash. | |
Installation locations | |
The first thing to do is decide on where you will install Pligg and WordPress. Pligg must be installed in either a directory on the same level as WordPress or a subdirectory of WordPress. In my code examples, I've installed WordPress and Pligg on the same level. I will refer to the WordPress directory as "wp" and Pligg as "p". So, for reference, I have Pligg and WordPress installed like this: | |
/public_html/wp | |
/public_html/p | |
Equally valid would be: | |
/public_html/wp | |
/public_html/wp/p | |
Pligg and WordPress should be part of the same domain. Otherwise the WordPress cookies won't be picked up by Pligg. | |
Installing the software | |
Install WordPress normally and configured it how you will. Make sure it's all working. Make a not eof your database prefix and site url. You can get your database prefix from 'wp-config.php'. It is the '$table_prefix' variable. Your site url (or URI if you want to be pedantic), is where you access WordPress from. You can get the exact value from your "Options", "General" panel when you log in to WordPress as admin. Your site url should have no trailing slash. It is important you get this right as you won't be able to log in to Pligg later otherwise. For example, if you install into a different directory, then your webpage's url will be different from your WordPress url. | |
Now install Pligg, but use the same database. Make sure everything is working, in particular that you can log in using the "god" account. | |
Modifying Pligg | |
All the work to modify Pligg takes place in 'libs/login.php'. What we want to do is get Pligg to login using WordPress cookies/authentication. If the user doesn't yet exist in Pligg, create it. Also, copy over all the existing user data to the Pligg database. We won't be using Pligg's login, authentication or logout any more. | |
However, we can't just include wordpress and call wordpress functions. Instead, we're going to have to do it manually. What I've done is added a function called is_user_logged_onto_wp(), which does all the extra work. | |
Here is the modified 'libs/login.php'. Make sure to correctly set the $wp_db_prefix to your database prefix (including the underscore) and $wp_siteurl to your WordPress url. | |
*/ | |
// The source code packaged with this file is Free Software, Copyright (C) 2005 by | |
// Ricardo Galli . | |
// It's licensed under the AFFERO GENERAL PUBLIC LICENSE unless stated otherwise. | |
// You can get copies of the licenses here: | |
// http://www.affero.org/oagpl.html | |
// AFFERO GENERAL PUBLIC LICENSE is also included in the file called "COPYING". | |
// Modified by Mark Cunningham | |
// (http://thedeadone.net). Log in using WordPress | |
// WordPress path (you don't really need this) | |
//if(!defined('WP_ROOT')) define('WP_ROOT', mnmpath.'/../wp/'); | |
// | |
// Can't do this, sadly as "get_permalink" collides in both code bases. | |
// Must do everything manually! | |
//require_once WP_ROOT.'wp-config.php'; | |
$wp_db_prefix = "wp_"; | |
$wp_siteurl = "http://www.myblog.com/wp"; | |
// Generate cookie keys! | |
if( !defined('WP_COOKIEHASH') ) { | |
// this value should be the same as siteurl | |
$cookiehash = md5($wp_siteurl); | |
define('WP_COOKIEHASH', $cookiehash); | |
} | |
if ( !defined('WP_USER_COOKIE') ) | |
define('WP_USER_COOKIE', 'wordpressuser_'. WP_COOKIEHASH); | |
if ( !defined('WP_PASS_COOKIE') ) | |
define('WP_PASS_COOKIE', 'wordpresspass_'. WP_COOKIEHASH); | |
// TODO: storing copy of password in pligg? | |
class UserAuth { | |
var $user_id = 0; | |
var $user_login = ""; | |
var $md5_pass = ""; | |
var $authenticated = FALSE; | |
function is_user_logged_onto_wp(){ | |
global $db, $wp_db_prefix; | |
// Most of this stuff I've taken (and modified) from WordPress codebase | |
// Do we have a username and password? | |
if ( !empty($_COOKIE[WP_USER_COOKIE]) && !empty($_COOKIE[WP_PASS_COOKIE]) ){ | |
$wp_username = $_COOKIE[WP_USER_COOKIE]; | |
$wp_password = $_COOKIE[WP_PASS_COOKIE]; | |
// Does the user exist in wordpress? | |
if(!$wp_user = $db->get_row("SELECT * FROM ".$wp_db_prefix."users WHERE user_login = '$wp_username'")){ | |
// User doesn't exist in wordpress… so… | |
// … should I delete this user in Pligg? | |
echo "This user $wp_username does not exist in WordPress!"; | |
return false; | |
} | |
// Grab data for user | |
$wp_userdata = $db->get_results("SELECT meta_key, meta_value FROM ".$wp_db_prefix."usermeta WHERE user_id = '$wp_user->ID'"); | |
if ($wp_userdata) { | |
foreach ( $wp_userdata as $meta ) { | |
@ $value = unserialize($meta->meta_value); | |
if ($value === FALSE) | |
$value = $meta->meta_value; | |
$wp_user->{$meta->meta_key} = $value; | |
// We need to set user_level from meta, not row | |
if ( $wp_db_prefix."user_level" == $meta->meta_key ) | |
$wp_user->user_level = $meta->meta_value; | |
} | |
} | |
// Check if username and password are valid! | |
if ( md5($wp_user->user_pass) != $wp_password) { | |
// bad password! | |
echo "Bad password in cookie for $wp_username!"; | |
return false; | |
} | |
// Okay, user exists and _is_ logged into wordpress! | |
// check if user exists in pligg! | |
$ok = 1; | |
// if a user doesn't exit… create the user | |
if(!user_exists($wp_username)){ | |
$userip = $_SERVER['REMOTE_ADDR']; | |
$ok = $db->query("INSERT INTO users (user_login, user_email, user_pass, user_date, user_ip) VALUES ('$wp_username', '$wp_user->user_email', 'password', now(), '$userip')"); | |
} | |
// if user creation was okay or user was already created, sync and log in | |
if($ok) { | |
// grab pligg user data | |
$user=$db->get_row("SELECT user_id, user_pass, user_login FROM users WHERE user_login = '$wp_username'"); | |
// Copy user data from wordpress! | |
$sql = "UPDATE users set "; | |
// admins should be set as "god" in pligg. What other levels should be mapped? | |
if($wp_user->user_level >= '10'){ | |
$sql .= "user_level='god', "; | |
} else { | |
$sql .= "user_level='normal', "; | |
} | |
$sql .= "user_date='$wp_user->user_registered', "; | |
$sql .= "user_url='$wp_user->user_url', "; | |
$sql .= "user_aim='$wp_user->user_aim', "; | |
$sql .= "user_yahoo='$wp_user->user_yim', "; | |
$sql .= "user_gtalk='$wp_user->jabber', "; | |
$sql .= "user_email='$wp_user->user_email' "; | |
$sql .= "WHERE user_id=$user->user_id"; | |
// there are other fields in pligg that don't exist in wordpress. | |
// Just ignoring them for the time being. | |
$db->query($sql); | |
// These are required for login to Pligg | |
$this->user_login = $user->user_login; | |
$this->user_id = $user->user_id; | |
$this->authenticated = TRUE; | |
$this->md5_pass = md5($user->user_pass); | |
$this->SetIDCookie(1, false); | |
// Oh, don't forget to log the ip! | |
$lastip=$_SERVER['REMOTE_ADDR']; | |
mysql_query("UPDATE users SET user_lastip = '$lastip' WHERE user_id = {$user->user_id} LIMIT 1?); | |
mysql_query("UPDATE users SET user_lastlogin = now() WHERE user_id = {$user->user_id} LIMIT 1?); | |
// All good! | |
return true; | |
} | |
else | |
{ | |
echo "Problem creating user in Pligg! | |
"; | |
} | |
} | |
else | |
{ | |
//debug | |
//echo "No wordpress user found!"; | |
} | |
return false; | |
} | |
function UserAuth() { | |
global $db; | |
// Are we logged into wordpress? | |
// Don't do anything unless we are! | |
if($this->is_user_logged_onto_wp()){ | |
if(isset($_COOKIE['mnm_user']) && isset($_COOKIE['mnm_key']) && $_COOKIE['mnm_user'] !== '') { | |
/* | |
Si ya está autentificado de antes, rellenamos la estructura. | |
*/ | |
$userInfo=explode(':', base64_decode($_REQUEST['mnm_key'])); | |
if(crypt($userInfo[0], 22)===$userInfo[1] | |
&& $_COOKIE['mnm_user'] === $userInfo[0]) { | |
$dbusername = $db->escape($_COOKIE['mnm_user']); | |
$dbuser=$db->get_row("SELECT user_id, user_pass, user_level FROM users WHERE user_login = '$dbusername'"); | |
if($dbuser->user_id > 0 && md5($dbuser->user_pass)==$userInfo[2]) { | |
$this->user_id = $dbuser->user_id; | |
$this->user_level = $dbuser->user_level; | |
$this->user_login = $userInfo[0]; | |
$this->md5_pass = $userInfo[2]; | |
$this->authenticated = TRUE; | |
} | |
} | |
} | |
// Logout of Pligg if not logged in to wordpress | |
} else { | |
$this->user_login = ""; | |
$this->authenticated = FALSE; | |
$this->SetIDCookie (0,false); | |
header("Cache-Control: no-cache, must-revalidate"); | |
header("Expires: " . gmdate("r", time()-3600)); | |
} | |
} | |
function SetIDCookie($what, $remember) { | |
switch ($what) { | |
case 0: // Borra cookie, logout | |
setcookie ("mnm_user", "", time()-3600, "/"); // Expiramos el cookie | |
setcookie ("mnm_key", "", time()-3600, "/"); // Expiramos el cookie | |
break; | |
case 1: //Usuario logeado, actualiza el cookie | |
// Atencion, cambiar aqu?cuando se cambie el password de base de datos a MD5 | |
$strCookie=base64_encode(join(':', | |
array( | |
$this->user_login, | |
crypt($this->user_login, 22), | |
$this->md5_pass) | |
) | |
); | |
if($remember) $time = time() + 3600000; // Lo dejamos v?idos por 1000 horas | |
else $time = 0; | |
setcookie("mnm_user", $this->user_login, $time, "/"); | |
setcookie("mnm_key", $strCookie, $time, "/"); | |
break; | |
} | |
} | |
function Authenticate($username, $pass, $remember=false) { | |
global $db; | |
$dbusername=$db->escape($username); | |
$user=$db->get_row("SELECT user_id, user_pass, user_login FROM users WHERE user_login = '$dbusername'"); | |
$saltedpass=generateHash($pass, substr($user->user_pass, 0, SALT_LENGTH)); | |
if ($user->user_id > 0 && $user->user_pass === $saltedpass) { | |
$this->user_login = $user->user_login; | |
$this->user_id = $user->user_id; | |
$this->authenticated = TRUE; | |
$this->md5_pass = md5($user->user_pass); | |
$this->SetIDCookie(1, $remember); | |
$lastip=$_SERVER['REMOTE_ADDR']; | |
mysql_query("UPDATE users SET user_lastip = '$lastip' WHERE user_id = {$user->user_id} LIMIT 1?); | |
mysql_query("UPDATE users SET user_lastlogin = now() WHERE user_id = {$user->user_id} LIMIT 1?); | |
return true; | |
} | |
return false; | |
} | |
function Logout($url='./') { | |
$this->user_login = ""; | |
$this->authenticated = FALSE; | |
$this->SetIDCookie (0); | |
//header("Pragma: no-cache"); | |
header("Cache-Control: no-cache, must-revalidate"); | |
header("Location: $url"); | |
header("Expires: " . gmdate("r", time()-3600)); | |
header("ETag: \"logingout" . time(). "\""); | |
die; | |
} | |
} | |
$current_user = new UserAuth(); | |
/* | |
Now login to wordpress and go to your Pligg frontpage. You may have to reload, but you should be automatically logged into Pligg! Remember, don't use Pligg's login or logout any more. I'll deal with what you need to change in the templates to handle that soon. If you use your wordpress admin account, you'll have full 'god' mode in Pligg. | |
Final modifications | |
Your site isn't fully secure yet. Delete 'register.php' so that no-one can create accounts using Pligg. We can also simply remove 'login.php' but lets not be so drastic. Lets modify 'login.php. Look for these lines: | |
*/ | |
if($_POST["processlogin"] == 1) { | |
$username = trim($_POST['username']); | |
$password = trim($_POST['password']); | |
$persistent = $_POST['persistent']; | |
if($current_user->Authenticate($username, $password, $persisten$ | |
$errorMsg=PLIGG_Visual_Login_Error; | |
} else { | |
if(strlen($_REQUEST['return']) > 1) { | |
header('Location: '.$_REQUEST['return']); | |
} else { | |
header('Location: '.my_pligg_base.'/'); | |
} | |
die; | |
} | |
} | |
/* | |
* We want to prevent hackers from using direct URLs to log in. So comment out the normal authentication test, as below. | |
*/ | |
if($_POST["processlogin"] == 1) { | |
$username = trim($_POST['username']); | |
$password = trim($_POST['password']); | |
$persistent = $_POST['persistent']; | |
if($current_user->Authenticate($username, $password, $persisten$ | |
$errorMsg=PLIGG_Visual_Login_Error;} else { | |
if(strlen($_REQUEST['return']) > 1) { | |
header('Location: '.$_REQUEST['return']); | |
} else { | |
header('Location: '.my_pligg_base.'/'); | |
} | |
die; | |
} | |
} | |
/* | |
Pligg also comes preconfigured with one special user account, the "god" account. You can't delete this account via the admin interface. You can create the "god" account in WordPress to prevent some user creating it and gaining "god" rights on Pligg. Or if you know sql or have access some sort of web access to your database, you can rename the "god" account to match the username of an existing admin user or delete the user outright. | |
Required Template Changes | |
So, now your WordPress users can log in on WordPress and then be automatically logged in to Pligg. But you've got to point the login, logout and register links to your WordPress equivelents. If your happy enough modifying the template then your ready to go. However, heres a run down of the minimal changes required to make sure it's okay. | |
Lets create a copy of the existing template, mollio-beat. To do this, just make a copy of 'templates/mollio-beat' in 'templates/' (including all subdirectories). Make sure the permissions are correct, etc. I renamed this copy "gcg1? (for Game Crafters Guild version1), so I now had a 'template/gcg1'. I went into the admin interface in Pligg and under the Template configuration, changed 'mollio-beat' to 'gcg1' and disabled the option that lets users change the template. We don't want users being able to go back to the old way of authentication. | |
We can't use WordPress template tags. You can always write PHP and SQL code that access the data manually in your database if your that way inclined. This means we have to use direct links. | |
template/gcg1/header.tpl | |
Open up 'template/gcg1/header.tpl'. Look for these lines: | |
{#PLIGG_Visual_Logout#} | |
{else} | |
{#PLIGG_Visual_Login#} | |
{#PLIGG_Visual_Register#} | |
Change them to: | |
{#PLIGG_Visual_Login#} | |
{#PLIGG_Visual_Register#} | |
Note: In my installation of Pligg, I've updated "my_base_url" (via the admin interface) correctly. I also have WordPress as a subdirectory of that same base url, so it became a handy shortcut to use '{$my_base_url}/wp' to reference any WordPress links directly. | |
header.tpl controls the header of all the Pligg pages so these changes will make sure those login, logout and register links are fixed across the entire Pligg site. | |
template/gcg1/profile_center.tpl | |
'template/gcg1/profile_center.tpl' controls what users can modify in their profile. We'll want to disable as much as possible of this as their profiles are overwritten from WordPress everytime they login. | |
Some where in the file, add this so users know where to modify their profile: | |
Please use this form to modify your profile. | |
Delete these lines. Users won't be able to modify their passwords here, so remove the option: | |
{#PLIGG_Visual_Profile_ChangePass#} | |
{#PLIGG_Visual_Profile_NewPass#}: | |
{#PLIGG_Visual_Profile_VerifyNewPass#}: | |
Now we need to disable the fields that are copied over by wordpress. These are aim, email, yahoo, url and gtalk. | |
{#PLIGG_Visual_Profile_OnlyAdmins#} | |
template/gcg1/story_center.tpl | |
'template/gcg1/story_center.tpl' controls the display of individual stories. If a non-logged in user, views a story, they will see a login and logout link! | |
Replace: | |
{#PLIGG_Visual_Story_LoginToComment#} {#PLIGG_Visual_Story_Register#} {#PLIGG_Visual_Story_RegisterHere#}. | |
With: | |
Login | |
Register | |
template/gcg1/sidebar/login.tpl | |
'template/gcg1/sidebar/login.tpl' is the sidebar login form you see. Replace it with this: | |
{#PLIGG_Visual_Login_Title#} | |
Register | |
Login | |
template/gcg1/sidebar/logged_in.tpl | |
'template/gcg1/sidebar/logged_in.tpl' is the sidebar panel you see when logged in. Replace the logout link: | |
{#PLIGG_Visual_Logout#} | |
With something like this: | |
{#PLIGG_Visual_Logout#} | |
I also add a link to the WordPress Admin panel for convience here. | |
WP Admin | |
Ready to go! | |
After all these changes, you should be able to login using WordPress only and be logged in on your Pligg page too! If you have any comments, feedback or find any bugs, just leave a comment here. Thanks. | |
*/ | |
//Delete pligg user | |
function delete_pligg_user( $user_id ) { | |
global $wpdb; | |
$user_obj = get_userdata( $user_id ); | |
$email = $user_obj->user_email; | |
//Delete Pligg user | |
//Send email | |
$headers = 'From: ' . get_bloginfo( "name" ) . ' <' . get_bloginfo( "admin_email" ) . '>' . "\r\n"; | |
wp_mail( $email, 'You are being deleted, brah', 'Your account at ' . get_bloginfo("name") . ' is being deleted right now.', $headers ); | |
} | |
add_action( 'delete_user', 'delete_pligg_user' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment