Integrating Pligg beta 8.1.0 with WordPress 2.0.4 (v1.1)

I’ve managed to get Pliggto use WordPress authentication and user database. You can see it running on the Game Crafter’s Guild website.

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 Beta 8.1.0. 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.

Version History

1.1 (19/10/2006)

Stray header redirection in login.php removed.

1.0 (17/09/2006)

First Release

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.

< ?php
// 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();
?>
[/soure]

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:

1
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#}

    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.

    Related Posts:

    Comments (20)

    1. Mark wrote::


      A short update: a stray header redirection in login.php was removed. This would cause some browers to not be able to see your Pligg site if not logged in. Particularly noticable with IE6.

      Thursday, October 19, 2006 at 4:18 pm #
    2. CK wrote::


      Hi,

      Thanks for your tip. Is it possible to integrate pligg with external LDAP server?

      Saturday, October 28, 2006 at 2:26 pm #
    3. Mark wrote::


      I guess it should be CK. I’m not sure how you would do it, but certainly would involve re-working login.php.

      Monday, October 30, 2006 at 9:37 pm #
    4. Alex wrote::


      Very great ! Our tip work with WordPress MU ???
      Thanks !

      Saturday, February 3, 2007 at 8:36 pm #
    5. Andrei wrote::


      Have you tested this with later versions of Pligg? I’m using Pligg 9.6 and want to integrate it with a new installation of WP 2.2

      Tuesday, June 19, 2007 at 2:28 am #
    6. Mark wrote::


      Have you tested this with later versions of Pligg? I’m using Pligg 9.6 and want to integrate it with a new installation of WP 2.2

      I’m afraid not Andrei. I plan to, but I haven’t gotten around to it (what with our second baby going to pop out any day now…). If you do get the chance, could you drop me a line (or a comment) about how sucessful you were?

      Tuesday, June 19, 2007 at 8:06 am #
    7. mark herpel wrote::


      hey, can someone install this in my blog and I’ll pay?
      my blog is http://www.dgcblog.com

      here is my pligg http://www.dgctags.com v. is the newest one with patches
      wordpress is also the newest one.

      any help will be compensated nicely
      contact me panama@cryptoheaven.com anytime

      Skype ‘digitalcurrency’

      Saturday, July 14, 2007 at 1:12 am #
    8. James wrote::


      Mark – Thanks – this is great. I think I’ve got it working with Pligg 9.5 and WP 2.2 – although I had to make a couple of changes.

      In login.php I had to take out the space between “

      Thursday, September 13, 2007 at 4:43 pm #
    9. James wrote::


      Hmm – my comment broke your system!

      Take out the space between

      Thursday, September 13, 2007 at 4:45 pm #
    10. Mark wrote::


      Hi James, oh dear! Did you try the “preview” button first before you placed your comment?

      Thursday, September 13, 2007 at 6:50 pm #
    11. James wrote::


      Yeah, thought it worked… Anyway, it turns out your hack and Pligg 9 / WP 2.2 aren’t working out so fine after all. I log in to WP, then go to Pligg (which is in a subfile of the WP install), and I’m not logged in. If I try to log into the Pligg install with my WP login, this appears at the top of the page:

      Warning: Table ‘dbname.users’ doesn’t exist in /home/public_html/wordpress/news/libs/db.php on line 233

      (dbname is correct, as is the path – just changed them as it’s a client project)

      The table users is there in the DB – although it’s called wp_users… the prefix is correct in login.php …

      Not sure my php/mysql skills are up to it, so might just install Pligg 8 and see if I can make that work…

      [p.s. Previewed this one!]

      Friday, September 14, 2007 at 10:33 am #
    12. Bruno wrote::


      Hello.

      Nice article, thanks! Do you think that other parts of Pligg are as easy to extend as this one? I want to aggregate RSS feeds that I have to authenticate in SharePoint 2007 to use – you think this is feasible?

      Thanks!

      Tuesday, January 8, 2008 at 7:42 pm #
    13. Mark wrote::


      Pligg are as easy to extend as this one? I want to aggregate RSS feeds that I have to authenticate in SharePoint 2007 to use – you think this is feasible?

      “SharePoint 2007″? I’m unfamiliar with that piece of software. If your asking if the autentication for Pligg can be extended to 2007, I’m not sure tbh. What exactly are you trying to do?

      Thursday, January 10, 2008 at 12:52 pm #
    14. Bruno wrote::


      Sharepoint 2007 is an intranet “portal” thing by Microsoft (http://en.wikipedia.org/wiki/SharePoint_Services#Windows_SharePoint_Services) that features, for one, exporting RSSs. These RSSs are behind https (with authentication) links, so Pligg can’t access them now. But it’s okay, I’ve noticed that this is more a RSS Importer plugin feature request than for Pligg itself.

      Thanks for you reply, anyway :)

      Thursday, January 10, 2008 at 2:16 pm #
    15. featuritis wrote::


      Does this integration work with WordPress v2.5 and and latest pligg version?

      Friday, April 4, 2008 at 3:15 pm #
    16. admin wrote::


      I’m sorry featuritis, but I doubt it. I haven’t tried it myself but some of the user stuff has changed in WP2.5.

      Friday, April 4, 2008 at 4:01 pm #
    17. gaurav wrote::


      first of all thanks for the script
      i tried to do according to your instructions
      but got lots of error
      and couldn’t make it
      it is a request if you could upload a php file with code in it then it will be easy for us

      thanks

      Friday, July 3, 2009 at 1:45 pm #
    18. pligger wrote::


      sound very difficult. is there pligg plugin for wordpress? i’ve been looking for one but coundt find it.

      Saturday, January 2, 2010 at 11:33 pm #

    19. Hi ,i am using pligg 1.0.4 and i wnat to integrate it with wordpress, means pligg main site and wordpress blog.
      Can you help me please. I wouldbe thankful to you .
      My site is http://linkmarking.com
      Regards.Anudeep Kanwar

      Friday, June 4, 2010 at 1:41 pm #
    20. nikesbar wrote::


      Thanks for your tip. Is it possible to integrate pligg with external LDAP server?

      Saturday, December 10, 2011 at 7:40 am #

    Trackbacks/Pingbacks (2)

    1. Frustrating! [ thedeadone.net ] on Saturday, February 17, 2007 at 7:21 pm


      [...] Mark, filed in categories Blog, LiveJournal. Read More if you like this why not read the next or previous dated post. LiveJournal This post is avalible on my LiveJournal here. Trackbacks You can [...]


    2. [...] based on this: Software: Integrating Pligg beta 8.1.0 with WordPress 2.0.4 (v1.1) [ thedeadone.net ] What we did is hacked it to work with recent version of WordPress, as well as [...]