http://www.simplemachines.org/community/index.php?topic=173483.0
I've locked the guide topic to keep it strictly informational.
If you would like to see more information, or different information than what I have provided, please let me know in this topic.
Hi Orstio,
i have a feeling your guide is the answer to my problem... only thing, i have no idea how to start with your guide. Is there a simple example, like how should i use the hooks, or which file should i include in my own scripts?
which CMS bridge you have applied the hook systems? then i can download and view it myself...
thanks!
wahlau.
Good questions.
All of the bridges use the hook system. The file to include in your own scripts is mainly just SMF's index.php.
The simplest of the bridges is currently the iGamingCMS bridge. That would probably be a nice beginner example. The hooks are defined and used in the file smf.php of that package.
i tried, but i think i don't get it :)
say my system is stored in /, and smf in /forum. so i would perform the normal login from /index.php. Following your guide, i will include the hooks in /integrate.php.
so say when i wish to have the integration, in my index.php i will include /integrate.php, which will include /forum/index.php? as soon as i call the method integrate_login($username, $pass, $cookietime), the hooks will take place and i will automatically be logged into SMF system?
hope my example clarifies my understanding... thank you
No, the method integrate_login($username, $pass, $cookietime) will be called when a user attempts to login in SMF.
This would mean that your login form should submit to the integration:
<form action="integrate.php?action=login2" method="post">
In the integrate_login function, you would put the code that will log the user into the CMS.
but in that case integrate.php should never be used directly, right? since by loading integrate.php, it will display the standard login page of SMF (from my understanding, integrate.php has an include(/forum/index.php) line...)
thanks.. i have the feeling i am close to the solution. shall try tonight.
Hey,
I'm just delving into the world of SMF integration, and I really appreciate these hooks.
Being a computer geek, I have to say that my mind works a little differently and instructions may or may not teach me anything at all, no matter how good they are.
Give me one example of a plugin that uses these hooks, and I'm good to go. While I did see a snippet of code there, I was unable, initially, to relate where that code might go. SMF? The CMS? A plugin? (just as an example).
Basically, an example plugin with hooks would do wonders. I'm sure I'm not the only one that is incapable of relating to instructions :)
Ok,
I'm somewhat up to speed now, and I'm definitely going to be utilizing these hooks.
A couple observations:
integrate_register occurs JUST before the user registers. Which, unfortunately, means that it does not know the User ID, for instance. In my code, it is essential that the User ID is tracked. It really should be with any integration code, imho, to properly identify that individual.
I'm wondering if this hook might better occur right After the user registration, and include ID_MEMBER in it's array?
My other comment is that I think these hooks are great, and could be used for much more than integration with a little tweaking. I hope to see more this in future versions!
Yeah, that makes sense.
You can make the change yourself, actually. It's in Subs-Members.php:
// Call an optional function to validate the users' input.
if (isset($modSettings['integrate_register']) && function_exists($modSettings['integrate_register']))
$modSettings['integrate_register']($regOptions, $theme_vars);
// Register them into the database.
db_query("
INSERT INTO {$db_prefix}members
(" . implode(', ', array_keys($regOptions['register_vars'])) . ")
VALUES (" . implode(', ', $regOptions['register_vars']) . ')', __FILE__, __LINE__);
$memberID = db_insert_id();
Change to:
// Register them into the database.
db_query("
INSERT INTO {$db_prefix}members
(" . implode(', ', array_keys($regOptions['register_vars'])) . ")
VALUES (" . implode(', ', $regOptions['register_vars']) . ')', __FILE__, __LINE__);
$memberID = db_insert_id();
// Call an optional function to validate the users' input.
if (isset($modSettings['integrate_register']) && function_exists($modSettings['integrate_register']))
$modSettings['integrate_register']($regOptions, $theme_vars);
Then you'll just need to global $memberID in your integration function.
Hi orstilo,
THis is my code to integrate login from SMF to my CMS,but it don't work.Could you help me
<?php
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'integrate_change_email',
'integrate_reset_pass' => 'integrate_reset_pass',
'integrate_exit' => 'ig_smf_exit',
'integrate_logout' => 'integrate_logout',
'integrate_outgoing_email' => 'integrate_outgoing_email',
'integrate_login' => 'integrate_login',
'integrate_validate_login' => 'integrate_validate_login',
'integrate_redirect' => 'integrate_redirect',
'integrate_delete_member' => 'integrate_delete_member',
'integrate_register' => 'integrate_register',
'integrate_pre_load' => 'integrate_pre_load'
)));
require($smf_path."/index.php");
function integrate_login($user, $pass, $cookietime)
{
global $database;
$sql="SELECT * FROM #__bibi_account WHERE #__bibi_account.username='".trim($username)."'";
$database->setQuery($sql);
$row=$database->loadObjectList();
$pwd='';
if (count($row)>0 )
{
if ( $row[0]->activate==1)
{
if ($password == '') {
$pwd = 1;
$pwd = md5( $pwd );
}
else{
$pwd = trim( $password );
$pwd = md5($pwd);
}
$query="SELECT * FROM #__bibi_account WHERE password='".$pwd."' AND username='".trim($username)."'";
$database->setQuery($query);
$database->loadObject($rows);
if(count($rows)>0)
{
// set remember me cookie if selected
create_cookie('username',$rows->username,$cookieTime);
create_cookie('username',$rows->username,$cookieTime);
// Khoi tao Session
if(!session_id()){
session_start();
}
session_register('account_id');
//session_register('user_account_name');
session_register('username');
//session_register('user_account_email');
session_register('usertype');
session_register('useremail');
session_register('bibibdate');
session_register('bibipregnantdate');
//session_is_registered('user_account_name');
session_is_registered('username');
session_is_registered('usertype');
session_is_registered('useremail');
session_is_registered('bibibdate');
session_is_registered('bibipregnantdate');
//session_is_registered('user_account_email');
$sql1="SELECT * FROM #__bibi_profiles WHERE account_id=".$rows->account_id;
$database->setQuery($sql1);
$database->loadObject($List);
$_SESSION['account_id']=$rows->account_id;
$_SESSION['username']=$rows->username;
$_SESSION['useremail']=$rows->email;
$_SESSION['bibibdate']=$List->birthday;
$_SESSION['bibipregnantdate']=$List->pregnant_date;
session_write_close();
mosCache::cleanCache();
//// Chuc nang sau khi dang nhap
//$message="Xin chào : ". $rows->username;
//HtmlbibiAccount::activate($option,$message);
mosRedirect("index.php?option=bibicontent");
}
else
{
create_cookie('username','',$cookieTime);
create_cookie('password','',$cookieTime);
echo "<script>alert('Sai mật khẩu!'); window.history.go(-1); </script>\n";
}
}
else
{
create_cookie('username','',$cookieTime);
create_cookie('password','',$cookieTime);
echo "<script> alert('Người dùng chưa được Activate.'); window.history.go(-1); </script>\n";
}
}
else
{
create_cookie('username','',$cookieTime);
create_cookie('password','',$cookieTime);
echo "<script> alert('Người dùng chưa đăng ký.'); window.history.go(-1); </script>\n";
}
}
function checkUser($username,$password,$cookieTime)
{
}
function create_cookie($name, $value = "",$cookieTime=31536000)
{
$expires = time() + $cookieTime;
setcookie($name, $value, $expires,"/","");
}
?>
Either your CMS is Joomla, or you have a whole lot of Joomla code in there that you shouldn't.
Hello,
I would like to connect "automatically" my portal users to SMF. I have a form asking user/password, and I check in my tables if it is correct. Then, I would like to active SMF cookie. In simple words, what should I add to my program ?
Hello Orstio,
Thanks for the code to change integrate_register!
These hooks are great, and I'm almost done my plugin to utilize them.
I'm creating a plugin for others to use as well, so I'm a little scared to be moving that hook around and creating compatibility problems.
For now, my plugin will create it's own hook at that insertion point, so it will still be compatible with other systems that use integrate_register, as well as future versions of SMF which may end up having integrate_register in another location.
cheers!
I am not very well known with SMF at the moment but I am convinced it is very powerful forum software. I am planning to completely rebuild an existing website. This site contains currently a PHPBB forum and also a custom part (with written articles, a photogallery and more). Both parts use the same login information, but you still have to login twice. (If you log in at the forum, you are not logged in at the rest of the site, and otherwise).
Anyway, I would like to use SMF in the future for the forum. I already discovered some possibilities of SSI.php but these integration hooks seem to be more powerful.
My real question is: Is it possible to have only one central login (that of SMF of course) that is used for both forum and the rest of the site ? I'd like to have a possibility to login on the forum ánd on the other part of the site, but you need to login only once for both parts.
Although I read the topic about the integration hooks this did not become totally clear to me, could anybody tell me ?
Yes, the hooks allow you to use SMF's login procedure to login to both SMF and another application.
Quote from: Orstio on July 15, 2007, 11:55:07 AM
Yes, the hooks allow you to use SMF's login procedure to login to both SMF and another application.
Even if the login-form is on located on the other application ? (So that in fact no forum is seen when logging in to the other part of the site...)
That would be nicest :)
In order to use the SMF login hook, the form must submit to SMF.
Well, I feel free to ask some more ;)
How likely is it that these hooks will be available in SMF 2.0 too ? SMF 2.0 looks even more promising but in fact I don't want to wait for it to be released because I would like to start developing the rest of my site this holiday. If the integration hooks remain the same I can use 1.1.3 to develop and (hopefully) switch to 2.0 later.
Is anything known about that ?
The hooks will remain in 2.0.
right, I've been reading this and I think I am getting there.... but want to make sure.
On my own custom built cms when someone logs in, they need to be logged into the forum too so I would now have to use the SMF login with my CMS code in that?
When someone registers on my CMS, can I just call a hook to register on SMF too so it's transparent to the user?
Once I have go those two things sorted, I think the rest will fall into place. I don't want to do massive changes to my existing CMS and keep disruption to a minimum while I'm trying to get this to work.
Orstio,
Thank you very much for these hooks!
My bridge is now stable, and I have used the hooks extensively for it.
I do think that these hooks could be useful beyond integration, though.
After working with Wordpress...which uses hooks exclusively for all plugins, I feel like having both hooks and xml available for plugins would be the best way to go.
If SMF had a "plugins" folder, and all files in it were included within index.php (this is sort of how my bridge is structured), you would essentially be giving hook access to all plugin developers.
This could significantly limit the amount of code alterations in plugins, increase compatibility, and simply make them easier to write. For example, my plugin can now completely integrate SMF users with Wordpress, no simple task: but I only needed to add 3 lines of code to do it.
Essentially, plugins developers would still have the xml power to alter code, but the availability of hooks would allow them to write their plugins without altering any code whenever possible.
I feel like plugin developers would be getting the best of both worlds, and it would require very minimal alteration to accomplish.
Anyway,
Thanks, the hooks really did it for me!
Orstio,
I've read through the different hooks, I'm wondering is there a hook to simply create a new thread?
I want to write a php function that will create a new thread and put a single post in it.
puredemo,
You can use the createPost() function in Subs-Post.php to create a topic and/or post.
A hook would be used to call a function when a topic was made.
Thantos,
Thanks for the quick response. Best... sigline... ever.
I've been looking at these integration hooks but I'm not sure if what I need is possible, can anyone clarify this?
Right now we have a base SMF installation, and we use a CRM system which provides all of our member management as well as our website to these members, ecommerce etc.
Since our website already establishes unique username and passwords, I would like to have SMF first query its database to check if the user is an SMF user, and if so log the user in as usual. However if the user is not found would it be possible for SMF then to query our existing database using its xml interface, and look for the user there. Then if the user exists log them into SMF as well as create a record for them in SMF so the multiple queries would not be required all the time.
This way our existing users would gain access to SMF as well as our moderately large existing forum user base to continue uninterrupted use.
It seems like these integration hooks might work, but it almost seems like i might have to modify the core?
Am i on the right track or totally off base?
Thanks
No, you wouldn't need to modify the SMF core.
You would use the integrate_validate_login hook.
In your hook function, you would first check to see if the user already exists in SMF. If the user does not exist in SMF, you would check to see if the user exists in the CRM system. If the user does exist, you would write that user into SMF, and then return the function.
Can these hooks be used when SMF and the other application are physically located on seperate servers? And what would be the best bridge example to get an idea of how best to use the hooks? Have been wondering for some time how I could link SMF to my sites in-house authentication system to make it easier for my members to keep up-to-date on the forum and this looks like the answer to my problems, just not 100% sure how to implement.
Also one last Q, will these work with SMF 2.0 as they do currently?
QuoteCan these hooks be used when SMF and the other application are physically located on seperate servers?
They can, but I would never recommend it. XSS (cross-site scripting) is asking for script-kiddie trouble. It is always best to keep connected scripts on the same physical server.
QuoteAnd what would be the best bridge example to get an idea of how best to use the hooks?
The simplest would be the iGamingCMS bridge. The Mambo bridge has some more advanced integration.
QuoteHave been wondering for some time how I could link SMF to my sites in-house authentication system to make it easier for my members to keep up-to-date on the forum and this looks like the answer to my problems,
It's actually just the opposite. The hooks use SMF's authentication system to register and login, etc. to other scripts.
QuoteAlso one last Q, will these work with SMF 2.0 as they do currently?
The same integration hooks will exist in SMF 2.0. There may be more functionality added to the system overall, however, that may require changes to integrations as well.
Quote from: Orstio on August 29, 2007, 08:54:57 PM
It's actually just the opposite. The hooks use SMF's authentication system to register and login, etc. to other scripts.
Hmm, so maybe this wouldnt help me? Basically what I'm looking for is a way that when someone registers on my site, I can create a forum account for them, and similarly when they login to my site they can be logged into the forum without them having to enter their details twice. Is this not what I'm looking for?
Thanks for the quick response ;D
You would simply need to pass the registration info to SMF's registerMember function in Subs-Members.php to register them in SMF. Not sure exactly how you'd handle the login.
thanks
Great guide... I'm attempting to expand my Who's Online to cover other parts of my site. I've created a simple whos_online_function function so far for testing:
function whos_online_function($actions) {
return ('whoadmin_dumpdb');
}
I'm just trying to test at this point, I would have expected everyone's status to flip to "Backing up the database to file." but it didn't. I've added what I believe is the correct row to my settings table. Here's an export of it:
INSERT INTO `smf_settings` (`variable`, `value`) VALUES
('integrate_whos_online', 'whos_online_function');
Any advice? I'm sure I'm missing something simple.
Thanks
Mike
Where did you put the function? Is it in Who.php?
What you have there will return the text 'whoadmin_dumpdb'. If you want it from the language file, it needs to be $txt['whoadmin_dumpdb'].
Thanks Orstio, I included the function in a global PHP file that I include for all pages. So I should be returning the actual text I want displayed in Who's online? I.E. return ("testing a customized Who's Online message."); for example?
QuoteThanks Orstio, I included the function in a global PHP file that I include for all pages.
So, from where exactly is it included? It will need to be in the workflow before Who.php is executed.
QuoteSo I should be returning the actual text I want displayed in Who's online? I.E. return ("testing a customized Who's Online message."); for example?
Yes.
It's included in global.php, it's the first include call made in the script and one of the first things to be done for all pages (forum and non-forum).
I changed the return value as above, but it still doesn't have any effect. I have the gallery mod installed which defines parts of SMF_INTEGRATION_SETTINGS already (but not integrate_whos_online). It doesn't seem like setting is taking for some reason though.
Any help is appreciated, thanks.
QuoteIt's included in global.php, it's the first include call made in the script and one of the first things to be done for all pages (forum and non-forum).
In what line of what file is it included? I need some details on where the include occurs in the workflow.
Sorry, I'm not trying to be vague, honest. :) When a non-forum page is loaded, the first thing it does is inclide_once global.php. global.php sets a couple of variables and then includes functions.php, which contains the whos_online_function function. It then includes SSI.php. Is that the workflow you're looking for?
BTW I noticed something odd... although my test status never shows up in who's online for my test user, a call to determineActions (in Who.php) will actually show them with the new status. So it's "almost" working.
Thanks!
Mike
QuoteSorry, I'm not trying to be vague, honest. When a non-forum page is loaded, the first thing it does is inclide_once global.php. global.php sets a couple of variables and then includes functions.php, which contains the whos_online_function function. It then includes SSI.php. Is that the workflow you're looking for?
Perfect.
So, that function is never included when the forum is loaded.
When you are looking at your Who's Online page, you have the forum loaded.
The whos_online_function needs to be in the workflow that produces the Who's Online page.
The easiest way to accomplish that if you haven't built a bridge up front is to tag it onto the end of SMF's Who.php.
Ah, that makes perfect sense! So I add the include for functions.php to Who.php then, and the forums already know when to call it?
That should work, yes, though you should be aware it will also add the overhead of your functions.php to your forum load.
PS: Something else you might also notice is that every external page shows as the forum main page in the whos online list. You can circumvent that by using the ssi_log_online function on the non-forum pages.
Thanks, I'll give that a shot. functions.php shouldn't add too much, it really just defines about 10 common functions but doesn't do too much else.
Thanks for the PS tip, I've noticed that too... I currently use writeLog(); but is ssi_log_online(); better?
Same thing. ;)
These hooks look like they might be just what I've been looking for. I'm building a site using CodeIgniter, and I want to integrate it with an SMF forum.
Here's the thing. Registering on a forum means looking at a whole lot of intimidating legalese. For example, here's the registration text for SMF:
QuoteYou agree, through your use of this forum, that you will not post any material which is false, defamatory, inaccurate, abusive, vulgar, hateful, harassing, obscene, profane, sexually oriented, threatening, invasive of a person's privacy, adult material, or otherwise in violation of any International or United States Federal law. You also agree not to post any copyrighted material unless you own the copyright or you have written consent from the owner of the copyrighted material. Spam, flooding, advertisements, chain letters, pyramid schemes, and solicitations are also forbidden on this forum.
Note that it is impossible for the staff or the owners of this forum to confirm the validity of posts. Please remember that we do not actively monitor the posted messages, and as such, are not responsible for the content contained within. We do not warrant the accuracy, completeness, or usefulness of any information presented. The posted messages express the views of the author, and not necessarily the views of this forum, its staff, its subsidiaries, or this forum's owner. Anyone who feels that a posted message is objectionable is encouraged to notify an administrator or moderator of this forum immediately. The staff and the owner of this forum reserve the right to remove objectionable content, within a reasonable time frame, if they determine that removal is necessary. This is a manual process, however, please realize that they may not be able to remove or edit particular messages immediately. This policy applies to member profile information as well.
You remain solely responsible for the content of your posted messages. Furthermore, you agree to indemnify and hold harmless the owners of this forum, any related websites to this forum, its staff, and its subsidiaries. The owners of this forum also reserve the right to reveal your identity (or any other related information collected on this service) in the event of a formal complaint or legal action arising from any situation caused by your use of this forum.
You have the ability, as you register, to choose your username. We advise that you keep the name appropriate. With this user account you are about to register, you agree to never give your password out to another person except an administrator, for your protection and for validity reasons. You also agree to NEVER use another person's account for any reason. We also HIGHLY recommend you use a complex and unique password for your account, to prevent account theft.
After you register and login to this forum, you will be able to fill out a detailed profile. It is your responsibility to present clean and accurate information. Any information the forum owner or staff determines to be inaccurate or vulgar in nature will be removed, with or without prior notice. Appropriate sanctions may be applicable.
Please note that with each post, your IP address is recorded, in the event that you need to be banned from this forum or your ISP contacted. This will only happen in the event of a major violation of this agreement.
Also note that the software places a cookie, a text file containing bits of information (such as your username and password), in your browser's cache. This is ONLY used to keep you logged in/out. The software does not collect or send any other form of information to your computer.
Yikes! I don't want to show all that to people who just want to register on the CI site I'm building. I just want them to be able to register quickly and easily, probably with email verification.
Of course, if they want to use the forum, then they need to see all that legalese.
I guess I could do this:
- Users could register on the forum, and my site will check the SMF database to look for their name and password when they log onto my site.
- Users could also register on my site and that auto-adds them to the forum. But then how do I make sure they see the legalese before they start posting to the forum?
Thanks in advance to all for any info.
You could add a field to the profile info (something like "seen_forum"), and set it to false. If they try to access the forum, and that field is false, you direct them to a page that shows them the TOS, and when they agree, the form submission sets it to true.
You could set this all up in CI, so it wouldn't need to touch the forum.
Thanks very much, Orstio. If they access the SMF forum from an SMF login page, is there a hook I can use to check the "seen_forum" field and direct them to the TOS page if necessary?
It depends where you would want to trigger it. You could do it on the login event with the integrate_login hook, or you could do it on the initial page load of the forum with the integrate_pre_load hook.
It is important to note that this hook occurs in the workflow before the user information is loaded, so that may be something you would need to do in the hook function.
Excellent! Now, I still have two questions about how these hooks are used.
1) To make them accessible, is it correct that I just put this at the top of my php code?
Quoterequire($smf_path."/index.php");
2) Suppose I want to use the integrate_login hook. How do I get my own code to be called via the integrate_login hook?
Thanks very much in advance for this great info!
Quote1) To make them accessible, is it correct that I just put this at the top of my php code?
Quote
require($smf_path."/index.php");
No, that will load and display SMF. It will also start up the hooks, but only because SMF is loaded.
What you need is the hook startup:
http://www.simplemachines.org/community/index.php?topic=173483.0#post_starting_up
Quote2) Suppose I want to use the integrate_login hook. How do I get my own code to be called via the integrate_login hook?
See the post linked above.
Okay, I think I'm starting to get it. I use the following array:
Quote//define the integration functions
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'change_email_function',
'integrate_change_member_data' => 'change_member_data_function',
'integrate_reset_pass' => 'reset_pass_function',
'integrate_exit' => 'exit_function',
'integrate_logout' => 'logout_function',
'integrate_outgoing_email' => 'outgoing_email_function',
'integrate_login' => 'login_function',
'integrate_validate_login' => 'validate_login_function',
'integrate_redirect' => 'redirect_function',
'integrate_delete_member' => 'delete_member_function',
'integrate_register' => 'register_function',
'integrate_pre_load' => 'pre_load_function',
'integrate_whos_online' => 'whos_online_function',
)));
For example, if I want to use the integrate_login hook, I edit the line for that function in the above array like this:
Quote'integrate_login' => 'my_login_function',
Then I define a function like this in my php code:
Quotefunction my_login_function()
{
}
...and it will be called by SMF at the correct time. Am I correct so far?
Now, I still think I need to somehow do some sort of a require or require once at the top of my php code, so that SMF gets started. Is this correct, and if so, what do SMF file do I use in the require statement?
You have the right idea.
The integrate_login hook is called during SMF's login procedure. So, as long as the form submits to SMF, you don't need to worry about including SMF in the workflow, because it will be the workflow.
What you will probably need to do is either create a whole bridge (similar to the Mambo bridge, where the entire SMF workflow is wrapped in the CMS), or include/require a file at the beginning of SMF that will define the integration array.
Quoteinclude/require a file at the beginning of SMF that will define the integration array.
That sounds like a very good way to go. How can I tell SMF where to find the php functions I specify in the SMF_INTEGRATION_SETTINGS array?
As long as that file is included near the beginning of SMF's index.php, it will find them.
You could also use the integrate_pre_include hook by adding the variable=>value pair to the smf_settings table:
integrate_pre_include => my_include_file.php
Very cool! So, I could have a library php file, that just contains the functions I need to use for the hooks.
I guess I should include this library file near the beginning of SMF's index.php, so that my functions will be called even if the user enters the system through SMF, rather than through my CI app.
QuoteAs long as that file is included near the beginning of SMF's index.php, it will find them.
Should I directly edit the SMF index.php file, to include my library file (via a 'require' statement), or is there a more elegant way to do this?
QuoteShould I directly edit the SMF index.php file, to include my library file (via a 'require' statement), or is there a more elegant way to do this?
Unfortunately, there is no better way at this time.
It's cool - it's just one line. This is very cool. Thank you so much for all your help!
I'm getting started today on implementing the good advice I have received here, and adding an SMF forum to my site. :)
When a user registers on my CI site, rather than on my SMF forum, I would like to auto-add them to my SMF forum database, as we discussed. What's the best way for me to do this? Should I use a routine from ssi.php, or from smf.api - or is there an even better way? Thanks very much in advance for your thoughts.
Try this:
http://www.simplemachines.org/community/index.php?topic=48220.msg344006#msg344006
Great. Thanks!
The integration is going very well. People can register, login, and logout from my main site, and they are automatically registered/logged in/logged out for my SMF forum. :)
I'm getting started now on using the SMF integration hooks. The first one I'm working on is integrate_login. I have the hook installed, and SMF is calling my PHP routine ("login_to_ci") on login. So far so good!
integrate_login passes parameters to my PHP routine, including $username, $hash_password, and $cookieTime.
I get the $username and $cookieTime, but the $hash_password is empty.
But that's easy to fix - if I declare
global $scripturl, $user_info, $user_settings;
in my routine, I can get the hash password from $user_settings.
The question is - what is the correct way for me to use a $hash_password - one that's been encrypted? Am I supposed to decrypt it? (Is that even possible?)
Thanks in advance for any info!
To provide a bit more info, I'm wondering how I can log a user onto my CI app (or register them if they've just registered on my SMF board), if I only have their password in an encrypted format?
Great to see that you're making progress! :)
QuoteI get the $username and $cookieTime, but the $hash_password is empty.
Are you using ssi_login? If so, you will probably want to use $_REQUEST['passwrd'] in your login_to_ci.
Quotein my routine, I can get the hash password from $user_settings.
The question is - what is the correct way for me to use a $hash_password - one that's been encrypted? Am I supposed to decrypt it? (Is that even possible?)
You can't decrypt it. Encryption is a one-way street.
Something you can count on is this: The integrate_login hook is called AFTER SMF has already validated the user. This means that the person has entered correct information as far as SMF is concerned. So, you can just read the data from your CMS and log the user into that automatically.
QuoteSomething you can count on is this: The integrate_login hook is called AFTER SMF has already validated the user. This means that the person has entered correct information as far as SMF is concerned. So, you can just read the data from your CMS and log the user into that automatically.
That's great advice. Thanks, Orstio!
I've got most of my site integration with SMF done, thanks in large part to you, Orstio! I really appreciate your advice.
I have a question about the "integrate_register" hook. If email validation is required to complete registration for SMF, does SMF call the "integrate_register" hook before, or after, email validation has taken place? If it takes place before, is there a way my app can find out, if email validation has been received by SMF? (Perhaps by a MySQL query?)
Thanks in advance for any info.
QuoteI have a question about the "integrate_register" hook. If email validation is required to complete registration for SMF, does SMF call the "integrate_register" hook before, or after, email validation has taken place?
Before.
QuoteIf it takes place before, is there a way my app can find out, if email validation has been received by SMF? (Perhaps by a MySQL query?)
SMF can tell your app through the integrate_activate (http://www.simplemachines.org/community/index.php?topic=173483.msg1106054#msg1106054) hook.
Fantastic. Thanks!
Hello,
I have a custom game that I want to integrate registered user with SMF + TP. Basically, what the code will need to do is check if SMF user is logged in and if it is true then it will send user's result to the database. That's pretty much it! Nothing too fancy than that. What do you recommend? Will SSI works or what?
I had somebody suggesting using global but I am not sure about that? And I wouldn't be familiar with SMF so I am not sure it is something I want to tweak with unless you can help?
Thanks!
I really don't understand how to use these hooks. :( How do I start using them?
Quote
Typically, when creating a bridge, I have SMF "wrapped" within the context of a CMS, so the startup is done in the CMS, as a part of the component/module that displays the forum.
Eh?
That's something that I've been trying to figure out for the last couple of weeks.... :(
I've read about everything there is to read, but I'm still no further than I was when I started out..... :'(
I need to integrate SMF/TP with TNG (http://www.lythgoes.net/genealogy/software.php) but have no clue as to where to begin....or how to use the integration hooks.
EDIT: OK....I want the user to register, sign on, and logout in SMF and automatically be signed into TNG...I went back over this thread and the integration hooks. Let's see if this is sinking in.....
I need to create a file to define the integration hooks....is this done in the SMF or TNG directory? Then I need to require/include the file at the beginning of SMF's index.php file??
Is this correct??
QuoteI need to create a file to define the integration hooks....is this done in the SMF or TNG directory?
The location of the file doesn't matter, as long as it is within the open_basedir restrictions of your SMF index.php.
QuoteThen I need to require/include the file at the beginning of SMF's index.php file??
That way will work. It's not the only way, but it is a viable method.
I have SMF/TP in my root directory and TNG in a subdirectory.....Is there a better way to do this?
I was reading your "How to integrate Registration" thread.....Is this something that I have to do first? Or can this be done with one of the integration hooks??
Thanks for your help.......
Ok... so let me get this straight, to use these hooks I have to include the index.php that has these functions defined. But if I include the index.php won't that just load up the forum.
You create a file to define the integration hooks and then you include the file in index.php....
I thought the whole point of these functions is to use SMF while not on the forum . For example I want to check if a user enters the correct login details but i don't want to log them into the forum.
Quote from: badams on January 16, 2008, 08:04:58 PM
I have SMF/TP in my root directory and TNG in a subdirectory.....Is there a better way to do this?
I was reading your "How to integrate Registration" thread.....Is this something that I have to do first? Or can this be done with one of the integration hooks??
Thanks for your help.......
The method you chose is fine.
The registration howto topic is more of a method of modifying another registration system to also register a user in SMF. That is a completely different method of integration than using the integration hooks.
Quote from: xXBenXx on January 16, 2008, 08:22:35 PM
I thought the whole point of these functions is to use SMF while not on the forum . For example I want to check if a user enters the correct login details but i don't want to log them into the forum.
You can use SSI to do that.
Ahh...so since I'm only going one way....SMF/TP to TNG....I don't need to use the other method since the registration is being handled by SMF....right?
In TNG's registration, it requires username, real name, password, and email address and performs a validation prior to writing it to the TNG database.....real name is not a requirement on the SMF side....do I need to add that to the SMF registration??
QuoteAhh...so since I'm only going one way....SMF/TP to TNG....I don't need to use the other method since the registration is being handled by SMF....right?
Correct.
QuoteIn TNG's registration, it requires username, real name, password, and email address and performs a validation prior to writing it to the TNG database.....real name is not a requirement on the SMF side....do I need to add that to the SMF registration??
You can, or you can just use the username for both. That's entirely up to you.
Since I'm creating the file to define the integration hooks in the SMF directory (root) and including the file in the SMF index.php.....Is there something I need to do on the TNG side??
You might want to redirect some links to SMF if TNG has its own registration and login system.
I think I'm on overload at the moment.... :)
But could you provide me an example of what types of links I would want to redirect?
Think I'm going to have to sleep on this tonight..... :)
Thanks again for your help.....
Links to a TNG registration page or login page.
I created the file for the integration hooks....but unsure where to include the file in the SMF index.php.
I know very little PHP....enough to be dangerous....looks like I'm going to have to pull out the books for this project....
You'll probably want it right after this:
// Load the settings...
require_once(dirname(__FILE__) . '/Settings.php');
Thanks, Orstio....at least you got me started. Do you have an example that I can be use as a guideline?
This may be a dumb question.....but how does TNG recognize the integration hooks if they are defined in a file in my SMF directory and included in the SMF index.php? In order to use the integration functions....doesn't the file have to be included or required in TNG?? So, that both SMF and TNG are aware of the hooks.....
It's been a good 15 years since I've done any programming....so, I'm a little rusty....:)
Since the user is already validated in SMF, I would be just checking the database and passing the variables in the integrate login function so that TNG can process the login.
Now I think you're starting to see something more. ;)
Read this topic, it might give you some ideas:
http://www.simplemachines.org/community/index.php?topic=217821.0
OK....Let's see if I understand what you're trying to tell me....:)
Within the integrate login function....I need to create an output buffer....require the TNG file/script that processes the login??....then replace/pass the smf variables to the TNG variables.....
Am I anywhere close....:)
Sorry, I didn't mean to confuse you so badly. :-[
No, you are absolutely wrong.
I was under the assumption you wanted to be able to login to TNG, and that would also log you into SMF, which doesn't seem to be what you're after.
QuoteSince the user is already validated in SMF, I would be just checking the database and passing the variables in the integrate login function so that TNG can process the login.
That statement is not quite correct. It should read: Since the user is already validated in SMF, you would be be processing the TNG login in the integrate_login function.
OK....so now I'm confused....which seems to be my normal state nowadays.... ;)
So, I'm back to the question....how does TNG know about the integration hooks.....so far it seems to be one sided....
For what you are trying to accomplish, it does not need to know.
OK....it seems like I need to reverse my way of thinking.....instead of SMF and TNG fighting over the steering wheel....SMF is the driver and TNG is the passenger.....therefore, TNG would not need to know....
With that being said....think I'll try some things tomorrow....
OK...I was so confused that I took a break and went back to square one... ;)
Working on integrate_login....both systems have their own registration and login procedures, as well as their own admin panels, etc. I want to use SMF/TP as the main site with TNG running as an application with the users signing on to SMF and being automatically logged into TNG.
With the integrate_login function, the membername, password, and cookietime is used. Since SMF uses SHA1 and TNG uses MD5....How do I compare the two passwords?
You don't need to compare them.
By the time the integrate_login function is triggered, the user is already authenticated in SMF. This is the authentic user, because they have already passed the SMF authentication.
So, you don't need to do another check in TNG to see if it is the authentic user, because the user has already been authenticated. You can just set the cookie for TNG.
OK....where am I going wrong in my line of thinking.....
I don't need to authenticate the user like you said....but I do need to set the session variables that sets the TNG permissions for the user and also set the logged in session variable showing that the user is signed into TNG. TNG performs a behind the scenes checklogin on every page that looks for these session variables. If the session variables are not set, then TNG is going to send you to a login screen and process the login.....
Since it appears that with integrate_login...I'm bypassing TNG's processlogin which logs the user in to TNG and sets the cookie....I manually need to set the cookie in integrate_login??
Correct.
Hmm.....that's going to be quite a bit of coding....better hit the books and get going..... :)
Hi,
Please help me.
In my template login.php, I have already defined the startup hooks then included SMF_Path/index.php but it doesn't work out...
e.g.
Template: Login.php
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'integrate_change_email',
'integrate_reset_pass' => 'integrate_reset_pass',
'integrate_exit' => 'ig_smf_exit',
'integrate_logout' => 'integrate_logout',
'integrate_outgoing_email' => 'integrate_outgoing_email',
'integrate_login' => 'integrate_login',
'integrate_validate_login' => 'integrate_validate_login',
'integrate_redirect' => 'integrate_redirect',
'integrate_delete_member' => 'integrate_delete_member',
'integrate_register' => 'integrate_register',
'integrate_pre_load' => 'integrate_pre_load'
)));
require_once(integration.php);
require_once(SMF_PATH/index.php);
Am I on the right track?
Thanks
QuoteIn my template login.php, I have already defined the startup hooks then included SMF_Path/index.php but it doesn't work out...
Where is this Login.php? Is it part of a CMS?
What is integration.php? What's in it?
Are you just trying to integrate logins? What it looks like you have done is included the entire forum, not just the login.
Hi,
"Where is this Login.php? Is it part of a CMS?"
Yes, Login.php is part of the CMS
"What is integration.php? What's in it?"
The integration functions.
"Are you just trying to integrate logins? What it looks like you have done is included the entire forum, not just the login."
I'm trying to integrate logins and registration.
What I'm trying to accomplish here to integrate SMF in my CMS with a single sign in.
Thanks in advance
I think you are approaching this backwards.
The SMF integration hooks use SMF functions to accomplish CMS tasks.
I think what you are trying to do is use your CMS login to login to SMF? That cannot be accomplished with this method.
The hook method uses SMF's login to log you into the CMS.
Btw, I'm using CMS login form not SMF ssi_login.
Thanks again.
Hi Orstio,
I'm very much thankful for your immediate reply...
I think it's more clearer now.
Thanks
Hi Orstio,
Last question. I have put SMF login to my CMS but how could I redirect it back to my CMS after login.
Thanks
You mean you have put the ssi_login() on your CMS? You redirect that by putting the URL in the function call:
ssi_login('URL');
But, that is not going to log you into your CMS.
Hi Orstio,
Here's what I did.
In my CMS/login.php
require_once('SSI.php');
ssi_login();
In which the action method points to SMF/index.php?action=login2
I was able to do a single sign-in in this approach.
My problem is. If I used my CMS/login.php, how can I redirect it back to my CMS/user_home.php?
Thanks
ssi_login('URL to CMS/user_home.php');
Hi,
In ssi_logout(CMS/home.php) is working as expected but in ssi_login(CMS/user_home) it does work. What could possibly cause this?
Thanks
ssi_login(CMS/user_home) it does not work.
You might have to set $_SESSION['login_url'] to the value before the login form.
Here is my code in login.php
{php}
ssi_login('http://CMS/user_home.php');
{/php}
Base on the content of ssi_login function if you pass an argument it would set a $_SESSION['login_url']..
Sorry, Im little lost in your login because when my action points SMF/index.php?action=login2 after this I am rediredted to SMF/index.php?action=login2&sa=check...
and in SMF/index.php?action=login2&sa=check... the $_SESSION['login_url'] is not set anymore
Right. So, you will probably have to change your code to this:
$_SESSION['login_url'] = 'http://CMS/';
ssi_login('http://CMS/user_home.php');
"$_SESSION['login_url'] = 'http://CMS/';
ssi_login('http://CMS/user_home.php'); "
This does not work either.
After clicking the submit SMF/index.php?action=login2 the $_SESSION['login_url'] has a value of http://CMS/user_home.php
but
after redirected to this link SMF/index.php?action=login2%3bsa=check%3bmember=14 the $_SESSION['login_url'] is empty.
What is your setting in SMF for database driven sessions?
I'm sorry I'm the one who set up this SMF. May I ask if where could find it? So, that I could tell you.
Thanks
In your SMF admin panel, Server Settings.
Could you just give me the variable name from the smf_settings co'z I don't know what is the password of the admin.
Thank you very much
Is the forum even on the same domain as the CMS?
yeah
The forum and CMS are in the same domain
Hello,
I'm using the 'integrate_change_member_data' hook like this:
'integrate_change_member_data' => 'updateprofile'
The function is:
function updateprofile(){
print_r($var);
print_r($data);
die();
}
After editing the profile, I have only a blank page and no information was sent, why?
Same problem with 'integrate_login': $user_settings is not returned
Thank you for your help.
Try this:
function updateprofile($memberNames, $var, $data){
print_r($var);
print_r($data);
die();
}
Thanks, Orstio, it works! But if I change the password, it is not sent so it's impossible to change it in my script.. Is there another way?
The password change is sent with the integrate_reset_pass (http://www.simplemachines.org/community/index.php?topic=173483.0#post_integrate_reset_pass) hook.
Sorry, I didn't see this hook! Thanks!
Hi there,
I've been trawling this forum, including the integration hooks guide and this comments thread and everything seems to be biased towards SMF being the most important thing on the server, ie. you use SMF's user system and everything else has to revolve around it!
I want SMF to be a small component of a system, an extra service for our users where, if they login to their account on our system they can also seamlessly access the forum. It's a complex and established system and switching over to using SMF's user management just isn't an option.
Has anybody got any simple examples of a setup like this that they would be willing to share? ...where an existing system is the source of user information and authentication.
I'm sure it must be possible to create some sort of generic wrapper script that could be configured to work with any existing users system in this way, and I will be more than happy to share with the SMF community any solution that I manage to get working!
I, like many others it seems, just can't seem to get my head around where to start! The documentation would really benefit from a collection of simplified real-world examples.
Any help would be greatly appreciated!
Regards
Simon
Are there also hooks available to retrieve all posts from a topic?
Integration hooks are for including outside functionality in the workflow of SMFat certain key events.
To retrieve posts, you should use SSI.php. No hooks necessary.
Is it possible to set Session variables in the integrate_login hook?
What I currently have is an area of my website that is built around phpbb2. The usernames and passwords etc... are registered in phpbb. When someone logs in my own code compares the username, password and active status of the account, sets a few different session variables and calls a phpbb function to set up the phpbb stuff. The user is then sent to the menu which they can do loads of stuff in, just one of them being a link to the actual forums.
I'm wanting to replace phpbb with smf. I've been playing with the integrate_login hook, by having a login page that uses the ssi_login() function giving the url of the main menu. I've then tried putting different things into my integrate_login() function, but havn't found a way of getting the required data set.
Am I doing this the right way? Is there another way? Can I set up the sessions this way? If not what's the best work around?
Many thanks
Phil
Hi Phil,
I'm going to need more information in order to help you.
Where are you putting the integrate_login function?
Where have you defined the integration hooks?
I'm trying to register users from my own website. The problem is that I've been trying to use these hooks, but dont know why, I couldn`t make them work. Could you explain me the file structure please?
Thanks, Jesus
PS: Sorry For My English xD
The hooks are for including outside code into SMF's workflow, not the other way around.
Hi Orstio
I have a file called PhilTest.php which just has the define('SMF_INTEGRATION_SETTINGS',serialize .... bit of code which I copy and pasted from somewhere, and includes the line 'integrate_login' => 'integrate_login',
I also have the function integrate_login($username,$password,$cookietime) in that file, and it is in that function that I am trying to set the session variables.
I have amended the index.php file to include the PhilTest.php file right after the Settings.php have been included.
I then have another file the includes SSI.php and uses the ssi_login() function with a URL as the parameter. When I go to this file I get text boxes for username and password. When I fill them in and click the button, I'm presented with the script at the URL I specified in the ssi_login() and am logged into smf, but the session variables I set in the integrate_login function aren't set.
I've tried echo'ing out some text in the integrate_login function, which can be seen briefly before it is redirected to the other URL.
Does that make sense? Am I being totally stupid!?! :(
Many thanks
Phil
Yep, makes perfect sense.
If you echo $context['sess_id'] on your PhilTest page, and also on your forum, are they the same value both before and after login?
I've tried to echo $context['sess_id'] in a number of places, but each time I'm getting a null string returned, which to me suggests I'm missing something!
Here are my files:
pjmlog.php
<?php
require('SSI.php');
$_SESSION['login_url'] = 'http://forums.mysite.com/';
ssi_login('http://forums.mysite.com/phil.php');
echo($context['sess_id']) ;
?>
PhilTest.php:
<?php
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'integrate_change_email',
'integrate_reset_pass' => 'integrate_reset_pass',
'integrate_exit' => 'ig_smf_exit',
'integrate_logout' => 'integrate_logout',
'integrate_outgoing_email' => 'integrate_outgoing_email',
'integrate_login' => 'integrate_login',
'integrate_validate_login' => 'integrate_validate_login',
'integrate_redirect' => 'integrate_redirect',
'integrate_delete_member' => 'integrate_delete_member',
'integrate_register' => 'integrate_register',
'integrate_pre_load' => 'integrate_pre_load'
)));
function integrate_login($username, $password, $cookietime)
{
global $pjmun, $db ;
$pjmun = "pjm" ;
$_SESSION["pjm"] = $pjmun ;
echo("HHHHHHHHHHHHHHHHHHHHHH<br><br>") ;
echo($context['sess_id']) ;
echo("<br><br>HHHHHHHHHHHHHHHHHHHHHH") ;
}
?>
phil.php
phil.php:
<?php
session_start();
global $pjmun ;
echo("UN: '" . $_SESSION["pjm"] . "'<br><br>") ;
echo($context['sess_id']) ;
?>
And the index.php is now like this:
// Load the settings...
require_once(dirname(__FILE__) . '/Settings.php');
require_once(dirname(__FILE__) . '/PhilTest.php');
Phil
Make it global first. ;)
How/where do I do that?
I've tried adding global $context ; to the top (nearly top anyway) of the pjmlog.php file, the integrate_login() function in PhilTest.php and the phil.php file, with the same restult as before.
Phil
Heh, sorry, my mistake. It should be $context['session_id'] . :-[
That's better! I've managed to get it working now. Spotted something in another thread. I've added a require('SSI.php'); into my phil.php, and can now see the $user_info array, and can set up my sessions there.
Thanks for your help.
Phil
My question is regarding the 'integrate_change_member_data' hook specifically.
The documentation around this function states that the variables are sent as arrays, but I've noted in practice that the only variable sent consistently as an array is memberNames
under what circumstances would arrays be passed for $vars and $data?
Upon further examination of the 'updateMemberData' function in Subs.php
if (!empty($memberNames))
foreach ($vars_to_integrate as $var)
call_user_func($modSettings['integrate_change_member_data'], $memberNames, $var, stripslashes($data[$var]));
I believe that only members will be passed as an array, and that the variable & data will need to be set for all members passed in the members array.
Someone please correct me if I'm wrong.
You are correct. I just looked through the same code myself. ;)
I've updated the post to reflect the correction. Thank you. :)
Im an struggling to understand the documentation given for this. I have now read thru all the posts on this topic twice in hope to understand, and on the 2nd read thru i managed to understand how to include these hooks (by editing the core index.php for smf.. which i thought was the reason for these hooks where not to edit the core files?)
I tried for some time to get the login hooks to work, but shortly found out, after quite a lot of fiddling, that the session data is wiped, and i can not think of a way to get my application to login (as their is no id or username returned after SMF login and redirect)
*the only ways ive thought, are insecure ways*
Here is a bit of what i have currently...
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_login' => 'wwc_integrate_login',
'integrate_change_email' => 'integrate_change_email',
'integrate_reset_pass' => 'integrate_reset_pass',
'integrate_exit' => 'ig_smf_exit',
'integrate_logout' => 'wwc_integrate_logout',
'integrate_outgoing_email' => 'integrate_outgoing_email',
'integrate_validate_login' => 'wwc_integrate_validate_login',
'integrate_verify_user' => 'wwc_integrate_verify_user',
'integrate_redirect' => 'wwc_integrate_redirect',
'integrate_delete_member' => 'integrate_delete_member',
'integrate_register' => 'integrate_register',
'integrate_pre_load' => 'integrate_pre_load'
)));
function wwc_integrate_login($username, $password, $cookietime)
{
global $wwctemp;
$wwctemp = "login";
}
function wwc_integrate_redirect($setLocation, $refresh)
{
global $wwctemp;
switch($wwctemp)
{
case 'login':
header("Location: /selector.php");
die();
break;
case 'logout':
header("Location: /index.php");
die();
break;
}
}
function wwc_integrate_logout()
{
global $wwctemp;
$wwctemp = "logout";
}
As you can see, i had to try flag the page which was sending the form, to know which redirect to do (this took some probing also), is this the correct way of doing so? (because this seems to be clearing the session data, such as if i added $_SESSION['data'] = '123', that would not be set once it goes to "/selector.php" at login...
article/help/tutorials for these hooks are near impossible (apart from the ones listed on the forum, which i already said, had difficulty following at all), why is that?
Thank you in advance for any help
Quoteand on the 2nd read thru i managed to understand how to include these hooks (by editing the core index.php for smf.. which i thought was the reason for these hooks where not to edit the core files?)
You could just put the code you've posted above in a file that includes SMF's index.php, instead of editing SMF's index.php.
QuoteI tried for some time to get the login hooks to work, but shortly found out, after quite a lot of fiddling, that the session data is wiped, and i can not think of a way to get my application to login (as their is no id or username returned after SMF login and redirect)
All that info is pased to the integrate_login hook. You need to put your login code for your other application in the wwc_integrate_login function.
Quote from: Orstio on July 26, 2008, 10:30:26 PM
Quoteand on the 2nd read thru i managed to understand how to include these hooks (by editing the core index.php for smf.. which i thought was the reason for these hooks where not to edit the core files?)
You could just put the code you've posted above in a file that includes SMF's index.php, instead of editing SMF's index.php.
QuoteI tried for some time to get the login hooks to work, but shortly found out, after quite a lot of fiddling, that the session data is wiped, and i can not think of a way to get my application to login (as their is no id or username returned after SMF login and redirect)
All that info is pased to the integrate_login hook. You need to put your login code for your other application in the wwc_integrate_login function.
Nope, that does not seem to work
Edited integrate login hook
function wwc_integrate_login($username, $password, $cookietime)
{
global $wwctemp;
$_SESSION['call'] = true;
$wwctemp = "login";
print "logging in...";
}As you see, session data is saved, so once the redirect is done the only values the session holds are "PHPSESSID" and "SMFCookie304".
Are you including SSI.php in selector.php?
Quote from: Orstio on July 27, 2008, 09:36:36 AM
Are you including SSI.php in selector.php?
No because that is the logged in page.
Unless im misunderstanding the use of the SSI functions (note: ive tested login using SSI and from forum login box to see if there was any difference)
*edit*
ah i see i had another re-read thru the source, and im guessing there is some kinda or reconstruction code in there for the session... run into another problem now, but might not be due to this. thanks
I'm not suggesting that you use any of the SSI functions.
By setting $_SESSION['call'] in the integrate_login hook, you are putting it into the SMF session. If you include SSI.php in selector.php, the SMF session will be started, and $_SESSION['call'] should then be accessible.
Quote from: Orstio on July 27, 2008, 09:42:08 AM
I'm not suggesting that you use any of the SSI functions.
By setting $_SESSION['call'] in the integrate_login hook, you are putting it into the SMF session. If you include SSI.php in selector.php, the SMF session will be started, and $_SESSION['call'] should then be accessible.
Yeah i kinda figured that out *see my edit* after you mentioned having ssi on the logged in page (kinda obvious really if there is some custom session handler in there some where...just have to add this to a few more pages now to get them working)
Sorry for this so newbie question, but i'm lost in this hook things.
I'm trying to make a login page in my site to use SMF validation login procedures. I tried to use SSI and it works if the credentials are correct, but when I get an error it jumps to the login error page of SMF and I want to do it in my login page.
I red the hook docs but I not sure if I can use it and how.
I have to create my login fuction but I should use
integrate_validate_login or not?
I'm lost...
Any help would be great.
PS - I will also need to make a custom registration form... :( I'm doomed...
QuoteI'm trying to make a login page in my site to use SMF validation login procedures. I tried to use SSI and it works if the credentials are correct, but when I get an error it jumps to the login error page of SMF and I want to do it in my login page.
You'll have to wait for SMF 2.0 for that.
QuoteI have to create my login fuction but I should use
integrate_validate_login or not?
integrate_validate_login happens before SMF validates the login. integrate_login happens after.
What I usually use integrate_validate_login for is to check to see if a user exists in SMF, and if not, to write the user into SMF from a CMS before SMF tries to validate.
Thanks Orsio
But how do you use it?
You have your custom Login page with user and pass.
The user tries to login in your page with a set of credentials, then you call integrate_validate_login with that set of credentials and if false you display an error message?
Can you give me a short example?
Thanks
Does the custom login page pass the credentials to SMF, or to some other script?
Orstio the idea is to pass them to SMF.
Is similar to SSI_login but I need to dealt with the errors (bans and so on) in my page.
A value of false returned from integrate_validate_login means nothing to SMF. It will continue its own login process as normal. If you want a redirect to an error message at that point, you need to do that in the integrate_validate_login function.
Ok Orstio. Seeming a little dumb.
So I need to change the integrate_validate_login to provide error codes correct?
So can you give me an "How to" use this?
I still can understand how to do it.
I'm assuming that I have a php with the html code to login, I submit the form and them call modified integrate_validate_login and act accordingly to the error codes, correct?
QuoteI'm assuming that I have a php with the html code to login, I submit the form and them call modified integrate_validate_login and act accordingly to the error codes, correct?
The integrate_validate_login function is called automatically whenever anyone attempts to login.
uhm... automatically?
How?
(once more sorry for seem so dumb)
SMF is really smart. ;)
SMF calls all of the hook functions automatically. All you need to do is create the function, and define it in the SMF_INTEGRATION_SETTINGS. SMF takes care of the rest.
Well SMF is, but I don't...
After trying to understand this I was unable to do it.
It seems that I want use a SSI version of the login but custom made and not to authenticate to SMF and my site .
Actually what I want is to use SMF database and make a custom made login page.
I'm driving myself beserk trying to understand this...
Well
I'm ding this:
//define the integration functions
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'change_email_function',
'integrate_change_member_data' => 'change_member_data_function',
'integrate_reset_pass' => 'reset_pass_function',
'integrate_exit' => 'exit_function',
'integrate_logout' => 'logout_function',
'integrate_outgoing_email' => 'outgoing_email_function',
'integrate_login' => 'login_function',
'integrate_validate_login' => 'validate_login_function',
'integrate_redirect' => 'redirect_function',
'integrate_delete_member' => 'delete_member_function',
'integrate_register' => 'register_function',
'integrate_pre_load' => 'pre_load_function',
'integrate_whos_online' => 'whos_online_function',
)));
if($_REQUEST['do']== "login") {
integrate_validate_login($_REQUEST['user'],$_REQUEST['passwrd'],'-1');
}
And.. error
This part of your code is completely useless:
if($_REQUEST['do']== "login") { integrate_validate_login($_REQUEST['user'],$_REQUEST['passwrd'],'-1');}
What you want to do is this:
//define the integration functionsdefine('SMF_INTEGRATION_SETTINGS', serialize(array( 'integrate_change_email' => 'change_email_function',
'integrate_change_member_data' => 'change_member_data_function',
'integrate_reset_pass' => 'reset_pass_function',
'integrate_exit' => 'exit_function',
'integrate_logout' => 'logout_function',
'integrate_outgoing_email' => 'outgoing_email_function',
'integrate_login' => 'login_function',
'integrate_validate_login' => 'validate_login_function',
'integrate_redirect' => 'redirect_function',
'integrate_delete_member' => 'delete_member_function',
'integrate_register' => 'register_function',
'integrate_pre_load' => 'pre_load_function',
'integrate_whos_online' => 'whos_online_function',)));
function validate_login_function ($user, $password, $cookietime){
// Check if the user already exists in SMF.
//OK, so if no user in SMF, does this user exist in the integrated software? Better check.
//If there is a result, let's write this one into SMF....
}
Hi Orstio,
I have a doubt. I have the following code in integrate.php. This file is included in index.php and all works perfectly. I want to verify that a user exists in smf_table. If user exists all is ok. If not exists, I want to verify that the user exists in another own database if exists, I insert that user in smf_members table. If not exist the user must to register in SMF. That's my idea.
<?php
//define the integration functions
define('SMF_INTEGRATION_SETTINGS', serialize(array(
//'integrate_pre_include' => 'integrate.php',
'integrate_change_email' => 'change_email_function',
'integrate_change_member_data' => 'change_member_data_function',
'integrate_reset_pass' => 'reset_pass_function',
'integrate_exit' => 'exit_function',
'integrate_logout' => 'logout_function',
'integrate_outgoing_email' => 'outgoing_email_function',
'integrate_login' => 'login_function',
'integrate_validate_login' => 'validate_login_function',
'integrate_redirect' => 'redirect_function',
'integrate_delete_member' => 'delete_member_function',
'integrate_register' => 'register_function',
'integrate_pre_load' => 'pre_load_function',
'integrate_whos_online' => 'whos_online_function',
)));
function validate_login_function ($user, $password, $cookieTime)
{
//echo "$user<br />";
//echo "$password<br />";
//echo "$cookieTime";
//database connection.
$link = mysql_connect('server', 'user', 'password');
$db_selected = mysql_select_db('database', $link);
//
//Does the user exist in smf_members table?
$query = "select * from smf_members where member_name='$user';";
$result = mysql_query($query);
if (mysql_num_rows($result)==0)
{//if
//The user does not exist. I must to verify that exist in another database
//If I suppose that the user exists in the another database, I insert the user in smf_members table.
$query="insert into smf_members(member_name,id_group,passwd,email_address) values('$user',0,'$password','$user')";
$result = mysql_query($query);
}//if
}
?>
Well, the insert was sucesfully but the user must to relogin to take effect the login. For example, I'm a user that not exist in smf_members but yes in the other database ... and then I make the insert to the smf_members, the insert is ok but the user must to write again his/her password to log in into the system ...
Why? I've hope explained clearly.
Sorry for my English and Thanks.
Alvaro.
WHen the user attempts the login, do they get the message "Password security has recently been updated. Please login again." ?
Nope,
Only if the function return true or "retry". If I dont return a value (like this case) o return false, the user goes to the homepage again when he/she try to log in to the system ...
Thanks
http://www.simplemachines.org/community/index.php?topic=173483.msg1105999#msg1105999
QuoteExample of use: A user that exists in the integrated application but not in SMF is attempting to login, so needs to ber migrated to SMF before SMF has a chance to authenticate. Something to keep in mind here is that SMF can authenticate with many other types of hashes, so the hashed passwords of other systems can typically be written directly to the SMF members table, with the hook returning 'retry', which will automatically invoke SMF to rewrite to its own hash on the second login attempt.
When writing in a foreign password hash, you should make the function return "retry".
Hi Orstio,
If I write a return "retry", when the user is inserted in the smf_members, the $password hash is empty, and I can see a message like that:
"Password security has recently been updated. Please login again."
Is it normal?
In the second attempt, must I update the register of that user to actually the $password?
Thanks for all.
Yes
Yes to all no?
Thanks Orstio,
All was perfectly...
Now a user sends his/her password and username of the other database, the system says that "Password security has recently been updated.", but in the second attempt, the user can enter into the system!!!
Thanks for all amigo.
Ciao.
Orstio,
Following your recommendation, i used integrate_verify_user hook to log users into SMF when they logged in to my main site. Everything worked fine till my host Cirtex moved to PHP5 and Apache 2. Seems that although i am able to see session variables that i am passing into the function , the function is not returning $ID_MEMBER
Could this be because Apache 2 doesnt like 'global $db_name, $db_prefix, $sql, $userdata;' ?
I am using SMF 1.1.4, PHP5 and Apache 2
When i was using SMF1.1.4, PHP4 and Apache 1 things were working !
Code i am using (index.php) . This bridges from PHPMotion to SMF
Thank you for all your help
Henry
<?php
include($_SERVER['DOCUMENT_ROOT'] ."/classes/config.php");
include($_SERVER['DOCUMENT_ROOT'] ."/classes/sessions.php");
include($_SERVER['DOCUMENT_ROOT'] ."/classes/menu.php");
if($_SESSION['user_name'] != NULL)
{
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_verify_user' => 'integrate_verify_user',
)));
function integrate_verify_user () {
global $db_name, $db_prefix, $sql, $userdata;
$query = mysql_query("SELECT ID_MEMBER FROM {$db_prefix}members WHERE memberName = '$_SESSION[user_name]'");
if (!(list($ID_MEMBER) = mysql_fetch_row($query))) {
mysql_query("INSERT INTO {$db_prefix}members
(memberName, realName, passwd, emailAddress, dateRegistered, ID_POST_GROUP, lngfile, buddy_list, pm_ignore_list, messageLabels, personalText, websiteTitle, websiteUrl, location, ICQ, MSN, hideEmail, signature, avatar, usertitle, memberIP, memberIP2, secretQuestion, additionalGroups)
VALUES ('$userdata[username]', '$userdata[forum_name]', '$userdata[password]', '$userdata[email]', ".time().", '4', '', '', '', '', '', '', '', '', '', '', '1', '', '', '', '', '', '', '')");
$ID_MEMBER = mysql_insert_id();
}
return $ID_MEMBER;
}
# Include the original index.php
include($_SERVER['DOCUMENT_ROOT'] . "/smf/index.inc.php");
}
else
{
// return $ID_MEMBER;
# Include the original index.php
include($_SERVER['DOCUMENT_ROOT'] . "/smf/index.inc.php");
}
?>
Are you trying to include SMF's index.php from inside the integrate_verify_user hook?
Yes. I have renamed it as index.inc.php
# Include the original index.php
include($_SERVER['DOCUMENT_ROOT'] . "/smf/index.inc.php");
This was actually working like a charm till a few days back when my host did all these updates ! Seems session data is getting lost once my index.php (in which the integrate_verify_user hook is called) calls this index.inc.php (which is essentially SMF's index.php file).
The hooks are called from SMF, so if you call SMF from the hooks as well, you end up with an endless loop.
Hi Ortiso,
Wonderd If You Could Help Me Ive Been Trying This All Nyt And I Cant Seem To Make It Work, I Have My Site In The Root And SMF In Forum Folder, I Dont Reli Understand How To Use These Functions
For Example On My Account-signup.php
// check if email addy is already in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where email='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is already in use.";
//check username isnt in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where username='$wantusername'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The username $wantusername is already in use.";
$secret = mksecret(); //generate secret field
$wantpassword = md5($wantpassword);//md5 hash the password
}
if ($message != "")
show_error_msg("Signup Failed", $message,1);
if ($message == "") {
if ($site_config["CONFIRMEMAIL"]){//req confirm email true/false
$status = "pending";
}else{
$status = "confirmed";
}
//make first member admin
if ($numsitemembers == '0')
$signupclass = '7';
else
$signupclass = '1';
$ret = mysql_query("INSERT INTO users (username, password, secret, email, status, added, age, country, gender, client, stylesheet, language, class) VALUES (" .
implode(",", array_map("sqlesc", array($wantusername, $wantpassword, $secret, $email, $status, get_date_time(), $age, $country, $gender, $client, $site_config["default_theme"], $site_config["default_language"], $signupclass))).")");
$id = mysql_insert_id();
integrate_register();
$psecret = md5($secret);
$thishost = $_SERVER["HTTP_HOST"];
$thisdomain = preg_replace('/^www\./is', "", $thishost);
Would I That Work If I Like Required A File The At The Top And Set It Out Like This
<?
//define the integration functions
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'change_email_function',
'integrate_change_member_data' => 'change_member_data_function',
'integrate_reset_pass' => 'reset_pass_function',
'integrate_exit' => 'exit_function',
'integrate_logout' => 'logout_function',
'integrate_outgoing_email' => 'outgoing_email_function',
'integrate_login' => 'login_function',
'integrate_validate_login' => 'validate_login_function',
'integrate_redirect' => 'redirect_function',
'integrate_delete_member' => 'delete_member_function',
'integrate_register' => 'register_function',
'integrate_pre_load' => 'pre_load_function',
'integrate_whos_online' => 'whos_online_function',
)));
function integrate_login($username, $password, $email, $secret, $md5 = false, $ip = 0) {
require_once("forum/Sources/Subs-Members.php");
GLOBAL $site_config;
if ($site_config['CONFIRMEMAIL']) {
$user_actkey = $secret;
$user_type = USER_INACTIVE;
$user_inactive_reason = INACTIVE_REGISTER;
$user_inactive_time = time();
} else {
$user_type = USER_NORMAL;
$user_actkey = '';
$user_inactive_reason = 0;
$user_inactive_time = 0;
}
$res = mysql_query('SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'REGISTERED' AND group_type = " . GROUP_SPECIAL) or die(mysql_error());
$row = mysql_fetch_row($res);
mysql_free_result($res);
$group_id = $row[0];
$user_row = array(
'username' => $username,
'user_password' => $md5 ? $password : smf_md5_hmac($password),
'user_email' => $email,
'group_id' => (int) $group_id,
'user_timezone' => 0,
'user_dst' => 1,
'user_lang' => 'en',
'user_type' => $user_type,
'user_actkey' => $user_actkey,
'user_ip' => $ip == 0 ? getip() : $ip,
'user_regdate' => time(),
'user_inactive_reason' => $user_inactive_reason,
'user_inactive_time' => $user_inactive_time,
);
$user_id = user_add($user_row);
}
?>
If You Could Jus Point Me In Right Direction Ill Be Grateful Thanks!
No.
The SMF integration hook functions are called from SMF. You do not ever need to add a line like this:
integrate_register();
THat is already done in SMF.
What you are trying to do has nothing at all to do with the integration hooks.
Erm... I Dont Understand Then I Just Want When Someone Signs Up To My Site They Get Signed Up At The Forum As Well Lol.
This Is The Whole Of My Account-Signup.php
<?
require_once("backend/functions.php");
dbconn();
//invite only check
if ($site_config["INVITEONLY"]){
show_error_msg("Invite only", "<br><br><center>Sorry this site has disabled user registration, the only way to register is via a invite from a existing member.<br><br></center>",1);
}
//get max members, and check how many users there is
$numsitemembers = get_row_count("users");
if ($numsitemembers >= $site_config["maxsiteusers"])
show_error_msg("Sorry...", "The site is full!<br>The limit of ".number_format($site_config["maxsiteusers"])." users have been reached.<br>HOWEVER, user accounts expire all the time so please check back again later!<BR><BR>There is currently ".number_format($numsitemembers)." members",1);
if ($takesignup == "1"){
$message == "";
function validusername($username) {
$allowedchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for ($i = 0; $i < strlen($username); ++$i)
if (strpos($allowedchars, $username[$i]) === false)
return false;
return true;
}
//Setup Error Messages
if (empty($wantpassword) || empty($email) || empty($wantusername))
$message = "Don't leave any required field blank.";
if (strlen($wantusername) > 12)
$message = "Sorry, username is too long (max is 12 chars)";
if ($wantpassword != $passagain)
$message = "The passwords didn't match! Must've typoed. Try again.";
if (strlen($wantpassword) < 6)
$message = "Sorry, password is too short (min is 6 chars)";
if (strlen($wantpassword) > 40)
$message = "Sorry, password is too long (max is 40 chars)";
if ($wantpassword == $wantusername)
$message = "Sorry, password cannot be same as user name.";
if (!validemail($email))
$message = "That doesn't look like a valid email address.";
if (!validusername($wantusername))
$message = "Invalid username.";
if ($message == "") {
//check email isnt banned
$maildomain = (substr($email, strpos($email, "@")+1));
$a = (@mysql_fetch_row(@mysql_query("select count(*) from email_bans where mail_domain='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is Banned All Been A Member And Banned.";
$a = (@mysql_fetch_row(@mysql_query("select count(*) from email_bans where mail_domain='$maildomain'"))) or die(mysql_error());if ($a[0] != 0)
$message = "The e-mail address $email is Banned Due To Being A Free Provider Address.";
// check if email addy is already in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where email='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is already in use.";
//check username isnt in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where username='$wantusername'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The username $wantusername is already in use.";
$secret = mksecret(); //generate secret field
$wantpassword = md5($wantpassword);//md5 hash the password
}
if ($message != "")
show_error_msg("Signup Failed", $message,1);
if ($message == "") {
if ($site_config["CONFIRMEMAIL"]){//req confirm email true/false
$status = "pending";
}else{
$status = "confirmed";
}
//make first member admin
if ($numsitemembers == '0')
$signupclass = '7';
else
$signupclass = '1';
$ret = mysql_query("INSERT INTO users (username, password, secret, email, status, added, age, country, gender, client, stylesheet, language, class) VALUES (" .
implode(",", array_map("sqlesc", array($wantusername, $wantpassword, $secret, $email, $status, get_date_time(), $age, $country, $gender, $client, $site_config["default_theme"], $site_config["default_language"], $signupclass))).")");
$id = mysql_insert_id();
$psecret = md5($secret);
$thishost = $_SERVER["HTTP_HOST"];
$thisdomain = preg_replace('/^www\./is', "", $thishost);
//ADMIN CONFIRM
if ($site_config["ACONFIRM"]) {
$body = "Your account at ".$site_config['SITENAME']." has been created.\n\nYou will have to wait for the approval of an admin before you can use your new account.\n\n".$site_config['SITENAME']." Admin";
}else{//NO ADMIN CONFIRM, BUT EMAIL CONFIRM
$body = "Your account at ".$site_config['SITENAME']." has been : APPROVED\n\nTo confirm your user registration, you have to follow this link:\n\n ".$site_config['SITEURL']."/account-confirm.php?id=$id&secret=$psecret\n\nAfter you do this, you will be able to use your new account.\n\n If you fail to do this, your account will be deleted within a few days.\n\n".$site_config['SITENAME']." Admin";
}
if ($site_config["CONFIRMEMAIL"]){ //email confirmation is on
ini_set("sendmail_from", "");
mail($email, "Your ".$site_config['SITENAME']." User Account", $body, "From: ".$site_config['SITENAME']." <".$site_config['SITEEMAIL'].">");
header("Refresh: 0; url=account-confirm-ok.php?type=signup&email=" . urlencode($email));
}else{ //email confirmation is off
header("Refresh: 0; url=account-confirm-ok.php?type=noconf");
}
//send pm to new user
if ($site_config["WELCOMEPMON"]){
$dt = sqlesc(get_date_time());
$msg = sqlesc($site_config["WELCOMEPMMSG"]);
mysql_query("INSERT INTO messages (sender, receiver, added, msg, poster) VALUES(0, $id, $dt, $msg, 0)");
}
die;
}
}//end takesignup
stdhead("Signup");
begin_frame("Signup");
?>
<? echo "" . COOKIES . "";?>
<p>
<form method="post" action="account-signup.php?takesignup=1">
<table cellSpacing="0" cellPadding="2" border="0" >
<tr>
<td>Username: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="text" size="40" name="wantusername" /></td>
</tr>
<tr>
<td>Password: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="password" size="40" name="wantpassword" /></td>
</tr>
<tr>
<td>Confirm: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="password" size="40" name="passagain" /></td>
</tr>
<tr>
<td>Email: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="text" size="40" name="email"/></td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" size="40" name="age" maxlength="3" /></td>
</tr>
<tr>
<td>Country:</td>
<td>
<select name="country" size="1">
<?php
$countries = "<option value=\"0\">---- None selected ----</option>\n";
$ct_r = mysql_query("SELECT id,name,domain from countries ORDER BY name") or die;
while ($ct_a = mysql_fetch_array($ct_r)) {
$countries .= "\t\t\t\t\t\t<option value=\"$ct_a[id]\"";
if ($dom == $ct_a["domain"])
$countries .= " SELECTED";
$countries .= ">$ct_a[name]</option>\n";
}
?>
<?=$countries ?>
</select>
</td>
</tr>
<tr>
<td>Gender:</td>
<td>
<input type="radio" name="gender" value="Male">Male
<input type="radio" name="gender" value="Female">Female
</td>
</tr>
<tr>
<td>Preferred BitTorrent Client:</td>
<td><input type="text" size="40" name="client" maxlength="20" /></td>
</tr>
<tr>
<td align="middle" colSpan="2">
<input type="submit" value="Sign Up" />
</td>
</tr>
</table>
</form>
<?
end_frame();
stdfoot();
?>
So What Would I Put To Insert The Data From This Signup Page Into SMF Database Aswell, My Files Are In Root And SMF Is In /forum folder.
I Seen The SSI Functions About The Recent News And There Was Easy To Do, Is Their Any Easy Ones I Could To Make My Users Signed Up At Mysite n forum n loggedin at same time
What you want is something more like this:
http://www.simplemachines.org/community/index.php?topic=48220.0
Hello, thanks a lot for your helpfull documentation!
I'm working on Integrate SMF in an CMS I'm working with (and which hadn't any Bridge yet).
I've just wrapped it into CMS-Content, but smf didn't seem to call my integration function. Here is my code:
... defining db-Objekt and Stuff...
//define the integration functions
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_verify_user' => 'verify_user',
)));
require ($SmfPfad . '/index.php');
echo "blubb";
function verify_user(){
echo "bla";
$db -> select_db($smfDatenbank);
$IdString ="SELECT ID_MEMBER FROM smf_members WHERE memberName=".$_SESSION["UserLogin"];
$IdErgebnis = $db -> sql ($IdString);
$IDa = mysql_fetch_array($IdErgebnis, MYSQL_ASSOC);
$ID = $IDa['ID_MEMBER'];
$db -> select_db($dbDatenbank);
return $ID;
}
so I see the forum and my first echo, but didn't see my second echo neither a user got logged in. Could you please help me, where my mistake is?
thanks in advance,
acid
Missing global?
... defining db-Objekt and Stuff...
//define the integration functions
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_verify_user' => 'verify_user',
)));
require ($SmfPfad . '/index.php');
echo "blubb";
function verify_user(){
global $db;
echo "bla";
$db -> select_db($smfDatenbank);
$IdString ="SELECT ID_MEMBER FROM smf_members WHERE memberName='".$_SESSION["UserLogin"]."'";
$IdErgebnis = $db -> sql ($IdString);
$IDa = mysql_fetch_array($IdErgebnis, MYSQL_ASSOC);
$ID = $IDa['ID_MEMBER'];
$db -> select_db($dbDatenbank);
return $ID;
}
EDIT -- And a SQL syntax error, already fixed in post.
Oh yeah, I allways forget those ', thnx ;)
edit:
Oh! I've got it! thnx! :D
acid
Finally, with all my courage, i post this thread after reading bunch and bunch of posts...
At fist, i read your Guide. It's totally no-starting point for people who just start using SMF. You does not point out of how, and which file to include, what to do, how the SMF can identify a file call smf.php which it never included.
So here's my questions: (I assume there's 2 party, which called CMS and SMF)
1/ How does SMF find out the hook file without actually modify a single line of code (require, include) !! -> I really don't understand how this work!!!!!
2/ Where to place the hook file? is it include in the CMS or in the SMF folder?
3/ For example, i dont want people to register, login, logout at SMF, but on CMS. is there a way to write the hook to SMF without modify SMF code and modify CMS code? (Just on the hook file itself)
Afterward, please, please stick this to your "A guide to the SMF integration hooks" so that people can find out where to start writing his/her hook because i see that there are too many people looking for what im looking for right now and i bet you dont want to repeat yourself for more than 10 times for 10 people. "DRY". Thank you!
Quote1/ How does SMF find out the hook file without actually modify a single line of code (require, include) !! -> I really don't understand how this work!!!!!
There are several ways to accomplish this. From a CMS, it is usually easiest to have the hook file include SMF's index.php.
Quote2/ Where to place the hook file? is it include in the CMS or in the SMF folder?
You can put it wherever you want it.
Quote3/ For example, i dont want people to register, login, logout at SMF, but on CMS.
Then the integration hooks are not what you are looking for. The integration hooks are part of the normal SMF workflow. If you want to use your CMS workflow, then you need to create something for your CMS to read/write from SMF. The integration hooks allow SMF to read/write from other systems.
Quote
There are several ways to accomplish this. From a CMS, it is usually easiest to have the hook file include SMF's index.php.
Can you be more specific? What are the way you talk about.
He's talking about something like
require_once('SMFPath/index.php');
Which will process everything SMF does and output the page.
Having a look at existing bridges/integrators might help you :).
require_once('SMFPath/index.php'); => in smf.php?
i though it must be
require_once('SMFPath/smf.php'); => in index.php?
because if we require it like the fist, how can SMF know the functions and hook call from SMF.php...
for example, the index.php link all the files for login, blah blah, when we access index.php?do=login, how can SMF i dentify the smf.php that it's linked 1 way to index.php?
require_once('SMFPath/index.php'); cause the hook to show the index.php.
Quoterequire_once('SMFPath/index.php'); => in smf.php?
Correct.
Quotei though it must be
require_once('SMFPath/smf.php'); => in index.php?
Incorrect. That would require changing SMF's index.php.
Quotebecause if we require it like the fist, how can SMF know the functions and hook call from SMF.php...
You set up the SMF_INTEGRATION_SETTINGS in smf.php before you include SMF's index.php. THat way SMF knows which functions to call.
Quotefor example, the index.php link all the files for login, blah blah, when we access index.php?do=login, how can SMF i dentify the smf.php that it's linked 1 way to index.php?
Your smf.php contains all the hook functions. Because those functions are already declared before SMF is included, SMF can easily find them.
so how do we call the function? login in SMF.php or normal login in index.php?
(smf.php?action=login) or (index.php?action=login)
base on my understanding:
we have SMF.php for the hook, and index.php for the index
SMF.php <---------- index.php (index.php included in SMF.php)
index.php <------------ other functions php file
which mean that index.php does not have anything to identify the SMF.php
how can they call/know the functions exist on SMF.php?
Here is your workflow:
Smf.php contains the integration array, and the hook functions. It also includes SMF's index.php:
define('SMF_INTEGRATION_SETTINGS',....));
function hook1($variable,$variable){
//code
}
include_once('/path/to/smf/index.php');
The integration functions are then "predefined", so SMF can use them in the workflow whenenver it needs to.
<?php
error_reporting(E_ALL);
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'change_email_function',
'integrate_change_member_data' => 'change_member_data_function',
'integrate_reset_pass' => 'reset_pass_function',
'integrate_exit' => 'exit_function',
'integrate_logout' => 'logout_function',
'integrate_outgoing_email' => 'outgoing_email_function',
'integrate_login' => 'login_function',
'integrate_validate_login' => 'validate_login_function',
'integrate_redirect' => 'redirect_function',
'integrate_delete_member' => 'delete_member_function',
'integrate_register' => 'register_function',
'integrate_pre_load' => 'pre_load_function',
'integrate_whos_online' => 'whos_online_function'
)));
require_once '/home/sandbox/public_html/settings.php';
require_once '/home/sandbox/public_html/includes/configure.php';
function validate_login_function($username, $password, $cookietime)
{
global $db, $user_settings;
$file = "/home/sandbox/public_html/content.txt";//$filename is given by Flash LoadVars
$handle = fopen($file, 'w+');
fwrite($handle, $username." - ".$password."\n");
fclose($handle);
}
function login_function($username, $password, $cookietime)
{
global $db, $user_settings;
$file = "/home/sandbox/public_html/content.txt";
$handle = fopen($file, 'w+');
fwrite($handle, $username." - ".$password."\n");
fclose($handle);
}
include_once('/home/sandbox/public_html/smf/index.php');
echo "ok!";
?>
for the sake of testing, i have the file smf.php located at: /home/sandbox/public_html/smf.php
and index at: /home/sandbox/public_html/smf/index.php
trying to login at SMF to see the output of the function. However, the content.txt is a blank file afterward.
im trying to get the explanation, afterward i will write a topic guide to start base on my experience. ^_^
You need to try to login at the URL of /home/sandbox/public_html/smf.php .
Hi Orstio, I read the guide to the "A guide to the SMF integration hooks" and I really like these hook functions. Thanks a lot for the great work!
I am new to SMF and I am trying to integrate SMF into my CMS. All my users have their uniq logins and passwords, and there is a link provided to them to SMF forum. When the user click the link, he will be redirect to SMF page and will be automatically logged in as their existing login/password.
After reading your "A guide to the SMF integration hooks" and lots of posts in this thread. I think integrate_verify_user is the right function I need to implement. Is that right?
I first just hard coded the function return a specific member_id, the auto-login part works fine. But logout does not. I tried to use some global variable $loggedIn, set it to false in integrate_logout, and SMF just keep logged in. Could you point out where I did wrong?
integrate_logout is called from SMF's logout function. Are you saying that logging out of MF does not work?
I am "greenhand". "reedforum" is a charter version of "greenhand" LOL
Quote from: Orstio on February 02, 2009, 07:55:45 PM
integrate_logout is called from SMF's logout function. Are you saying that logging out of MF does not work?
Here is the outline of my code:
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_logout' => 'integrate_logout',
'integrate_verify_user' => 'integrate_verify_user'
)));
$loggedIn = true;
include ($smf_dir . "index.php");
function integrate_verify_user()
{
global $loggedIn;
if ($loggedIn == true)
return 2;
else
return 0;
}
function integrate_logout()
{
global $loggedIn;
$loggedIn = false;
}
For simplicity, I hard coded return 2 and 0 from integrate_verify_user.
I can see the SMF automatically logged as member_id 2. But I can not logged out. Clicking "logout" button does not have any effect. I tried to print out the $loggedIn, it is always "true" in integrate_verify_user.
I must have missed something.
This is done at the beginning of every page load:
$loggedIn = true;
It doesn't matter what you do in integrate_logout, because the page gets loaded again, and that line is read before SMF is loaded.
Quote from: Orstio on February 02, 2009, 08:39:14 PM
This is done at the beginning of every page load:
$loggedIn = true;
It doesn't matter what you do in integrate_logout, because the page gets loaded again, and that line is read before SMF is loaded.
So what should I do in this scenario?
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_logout' => 'integrate_logout',
'integrate_verify_user' => 'integrate_verify_user'
)));
session_start();
if (!isset($_SESSION['loggedIn']))
$_SESSION['loggedIn']=true;
include ($smf_dir . "index.php");
function integrate_verify_user()
{
if ($_SESSION['loggedIn']==true)
return 2;
else
return 0;
}
function integrate_logout()
{
$_SESSION['loggedIn'] = false;
}
Orstio, thanks for your previous answers. Now I have another question.
User will input his login and password in smf's login page, and it need to authenticate the user against the existing CMS's database. If it is a valid user in the CMS database, I would like it automatically logged in SMF.
I am trying to use "integrate_validate_login" but as you mentioned in the guide, it is impossible to have the un-hashed password.
Am I using the correct function? What should I do here?
integrate_validate_login is more for just checking to see if the user exists in a system outside of SMF, and then migrating that user to SMF if it doesn't.
What you are looking for is a combination of the integrate_validate_login and integrate_login hooks.
In the integrate_validate_login hook, you'll want to migrate the user from your CMS to SMF, and then return the value "retry".
When the user attempts to login the second time, they will be logged in, and SMF will update the password with its own hash.
Quote from: Orstio on February 06, 2009, 09:42:05 PM
In the integrate_validate_login hook, you'll want to migrate the user from your CMS to SMF, and then return the value "retry".
When the user attempts to login the second time, they will be logged in, and SMF will update the password with its own hash.
In this case, the user is actually authenticated in the SMF. What I am looking for is authenticate every user against the CMS database. Keeping and using user credentials in two databases could be a potential maintenance problem.
I am looking for some like this:
1. user input login password in SMF's login name
2. authenticate the user against CMS's database
3. if user does not exist in SMF's members table, insert a new row for it (without password, because will never use it to authenticate user)
4. return the id_member and logged in SMF as the user.
Is it possible to implement in existing hook functions?
QuoteWhat I am looking for is authenticate every user against the CMS database. Keeping and using user credentials in two databases could be a potential maintenance problem.
SMF still needs to keep its own record in its own database table. There is no way around this short of rewriting most of SMF's authentication and security checks.
Hi Orstio,
I've been looking through your tutorials all the way in this forum. And they are great tutorials. Thank you.
Confusing in the beginning but after following others member post, I can managed to make login from my CMS and sucessfully auto login in SMF too.
But, I got trouble to logout from my CMS and auto logout from SMF too.
The error is "Session verification failed. Please try logging out and back in again, and then try again.".
For "Logout" link I tried to use ssi_logout("http://CMS/index.php") in my CMS menu.
Other method, I set session for $context["session_id"] variable in integrate_login function and I put a "Logout" link with "http://CMS/SMF/index.php?action=logout;sesc=".$context["session_id"]
Both ways didnt work, always got the above error message.
Below are the script of my smf_integrate php:
/*-- Define SMF Integratin Settings --*/
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_change_email' => 'integrate_change_email',
'integrate_reset_pass' => 'integrate_reset_pass',
'integrate_exit' => 'integrate_exit',
'integrate_logout' => 'integrate_logout',
'integrate_outgoing_email' => 'integrate_outgoing_email',
'integrate_login' => 'integrate_login',
'integrate_validate_login' => 'integrate_validate_login',
'integrate_redirect' => 'integrate_redirect',
'integrate_delete_member' => 'integrate_delete_member',
'integrate_register' => 'integrate_register',
'integrate_pre_load' => 'integrate_pre_load'
)));
function integrate_validate_login($username, $password, $cookietime)
{
global $db_config, $password, $sess, $ng_config, $context;
$dblink = mysql_connect($ng_config['db_server'], $ng_config['db_user'], $ng_config['db_pass']) or
die("Could not connect: " . mysql_error());
mysql_select_db($ng_config['db_name'], $dblink);
$sql = "SELECT * FROM ".$ng_config['db_name'].".ng_user WHERE user_name = '".$username."' AND passw = '".$password."'";
$rs = mysql_query($sql, $dblink);
$row = mysql_fetch_array($rs, MYSQL_ASSOC);
$num_rows = mysql_num_rows($rs);
if ($num_rows > 0) {
/*-- Set sessions --*/
$sess->set('session_UserID', trim($row["id"]));
$sess->set('session_Username', trim($row["user_name"]));
$sess->set('smf_session_id', $context['session_id']);
} else {
header("Location: ".$ng_config['ng_url_login']);
}
mysql_select_db($ng_config['smf_db_name'], $dblink);
}
function integrate_logout($username)
{
global $sess;
$sess->drop();
}
function integrate_redirect(&$setLocation, $refresh)
{
global $ng_config;
$setLocation = $ng_config['ng_url_redirect'];
$refresh = true;
return true;
}
For login form I use form that is generated from ssi_login() below:
<form action="http://CMS/SMF/index.php?action=login2" method="post" accept-charset="ISO-8859-1">
<table class="ssi_table" width="200" height="50" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="140"><input id="user" name="user" type="text" class="style6"></td>
<td width="60" rowspan="2"><a href=# onclick="document.forms[0].submit();"><input type="image" src="images/bt_login.jpg" name="Submit" d="submit" width="41" height="41" border="0"></a></td>
</tr>
<tr>
<td><input type="password" name="passwrd" id="passwrd" type="text" class="style6"></td>
</tr>
<input name="cookielength" value="-1" type="hidden">
</table>
</form>
in SMF/index.php after:
// Load the settings...
require_once(dirname(__FILE__) . '/Settings.php');
I put below line:
// SMF integration hook...
require_once(dirname(__FILE__) . '/smf_integrate.php');
My questions are:
1. How to get the exact "sesc" value that I can pass to "Logout" link?
2. As you can see in integrate_validate_login above, if the username is not in my CMS user table then to go back to my login url, i must use "header" function, is there any better way to do this? Because if I just return "false" or "retry" in that function, then it shows SMF login page instead of my CMS login page.
Thank you very much for your kindly help...
To get the right value for $sesc, you need to do this after including SSI.php:
$sc = &$context['session_id'];
$_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
The value in $sc is what you are after.
Thank you Orstio, now it works like a charm.
But for my second question, if user type wrong login name and/or passw, then it shows SMF login page, it should show my CMS login page again. Currently I use header() function in "integrate_validate_login" to move back to my CMS login page again
Is there any other way instead of using header() function?
I can't think of a better way just off hand. That is a very clever method of doing it. ;)
Wonderd If You Could Help Mate.
I have the signup workin great when they signup on my site they get put into the smfs database aswell but when i try to login it says Security has just been updated then i retry and it says incorrect password what am i doing wrong here his my file
<?
function createUser($wantusername, $email, $wantpassword){
global $db_name, $db_prefix, $sourcedir, $boarddir;
require_once ("forum/SSI.php");
// Set the options needed for registration.
$regOptions = array(
'interface' => 'guest',
'username' => $wantusername,
'email' => $email,
'password' => $wantpassword,
'password_check' => $wantpassword,
'check_reserved_name' => false,
'check_password_strength' => false,
'check_email_ban' => true,
'send_welcome_email' => false,
'require' => 'nothing',
'extra_register_vars' => array(),
'theme_vars' => array(),
);
if (isset($_POST['default_options']))
$_POST['options'] = isset($_POST['options']) ? $_POST['options'] + $_POST['default_options'] : $_POST['default_options'];
$regOptions['theme_vars'] = isset($_POST['options']) && is_array($_POST['options']) ? $_POST['options'] : array();
require_once($sourcedir . '/Subs-Members.php');
$memberID = registerMember($regOptions);
mysql_select_db($config["db_database"]);
}
?>
And Also I Have Alot Of Members On My Site And I Was Wondering If Their Is A Way I Could Use This Somehow To Import Them All Over??
This has nothing to do with the integration hooks, but I'll help you out anyway. ;)
Is $wantpassword hashed in any way? (MD5, SHA1, etc.?)
okai cheers and its md5 ;)
Is it salted, or just a straight MD5?
str8 md5
Please have enough respect for the English language to type out real words.
Is this SMF 1.1.x, or 2.0.x?
Sorry And Yes Mate Its 1.1.8
If you check the value in your SMF database for a password that was migrated in this way, does it match the MD5 in your other user table, or is it a different hash?
its different
That'll be the problem, then.
You'll probably want to echo $wantpassword to find out what value it is getting, and compare to the value entered in the database.
i did and below is what i got
testpass
Warning: Cannot modify header information - headers already sent by (output started at /home/sites/madhous3.co.uk/public_html/backend/smf.php:44) in /home/sites/madhous3.co.uk/public_html/backend/functions.php on line 31
Warning: Cannot modify header information - headers already sent by (output started at /home/sites/madhous3.co.uk/public_html/backend/smf.php:44) in /home/sites/madhous3.co.uk/public_html/forum/Sources/Subs.php on line 3196
Warning: Cannot modify header information - headers already sent by (output started at /home/sites/madhous3.co.uk/public_html/backend/smf.php:44) in /home/sites/madhous3.co.uk/public_html/forum/Sources/Subs.php on line 3197
Warning: Cannot modify header information - headers already sent by (output started at /home/sites/madhous3.co.uk/public_html/backend/smf.php:44) in /home/sites/madhous3.co.uk/public_html/forum/Sources/Subs.php on line 3203
Warning: Cannot modify header information - headers already sent by (output started at /home/sites/madhous3.co.uk/public_html/backend/smf.php:44) in /home/sites/madhous3.co.uk/public_html/forum/Sources/Subs.php on line 3206
i tried including sources/loginout with below but saying missing argument any ideas?
'password' => $md5 ? $wantpassword : MD5_hmac($wantpassword),
Quotei did and below is what i got
testpass
Warning: Cannot modify header information - headers already sent by (output started at /home/sites/madhous3.co.uk/public_html/backend/smf.php:44) in /home/sites/madhous3.co.uk/public_html/backend/functions.php on line 31
Then the variable $wantpassword is a raw text string, not a MD5 hash.
What you'll want to do is this:
'password' => sha1(strtolower($wantusername) . un_htmlspecialchars($wantpassword)),
'password_check' => sha1(strtolower($wantusername) . un_htmlspecialchars($wantpassword)),
nope that didnt work mate it says incorrect password :(
i have posted my account-signup.php im thinking rather then using $wantpassword will the $secret work ??
<?
require_once("backend/functions.php");
require_once("backend/smf.php");
dbconn();
//invite only check
if ($site_config["INVITEONLY"]){
show_error_msg("Invite only", "<br><br><center>Sorry this site has disabled user registration, the only way to register is via a invite from a existing member.<br><br></center>",1);
}
//get max members, and check how many users there is
$numsitemembers = get_row_count("users");
if ($numsitemembers >= $site_config["maxsiteusers"])
show_error_msg("Sorry...", "The site is full!<br>The limit of ".number_format($site_config["maxsiteusers"])." users have been reached.<br>HOWEVER, user accounts expire all the time so please check back again later!<BR><BR>There is currently ".number_format($numsitemembers)." members",1);
if ($takesignup == "1"){
$message == "";
function validusername($username) {
$allowedchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for ($i = 0; $i < strlen($username); ++$i)
if (strpos($allowedchars, $username[$i]) === false)
return false;
return true;
}
//Setup Error Messages
if (empty($wantpassword) || empty($email) || empty($wantusername))
$message = "Don't leave any required field blank.";
if (strlen($wantusername) > 12)
$message = "Sorry, username is too long (max is 12 chars)";
if ($wantpassword != $passagain)
$message = "The passwords didn't match! Must've typoed. Try again.";
if (strlen($wantpassword) < 6)
$message = "Sorry, password is too short (min is 6 chars)";
if (strlen($wantpassword) > 40)
$message = "Sorry, password is too long (max is 40 chars)";
if ($wantpassword == $wantusername)
$message = "Sorry, password cannot be same as user name.";
if (!validemail($email))
$message = "That doesn't look like a valid email address.";
if (!validusername($wantusername))
$message = "Invalid username.";
if ($message == "") {
//check email isnt banned
$maildomain = (substr($email, strpos($email, "@")+1));
$a = (@mysql_fetch_row(@mysql_query("select count(*) from email_bans where mail_domain='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is Banned All Been A Member And Banned.";
$a = (@mysql_fetch_row(@mysql_query("select count(*) from email_bans where mail_domain='$maildomain'"))) or die(mysql_error());if ($a[0] != 0)
$message = "The e-mail address $email is Banned Due To Being A Free Provider Address.";
// check if email addy is already in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where email='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is already in use.";
//check username isnt in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where username='$wantusername'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The username $wantusername is already in use.";
$secret = mksecret(); //generate secret field
$wantpassword = md5($wantpassword);//md5 hash the password
}
if ($message != "")
show_error_msg("Signup Failed", $message,1);
if ($message == "") {
if ($site_config["CONFIRMEMAIL"]){//req confirm email true/false
$status = "pending";
}else{
$status = "confirmed";
}
//make first member admin
if ($numsitemembers == '0')
$signupclass = '7';
else
$signupclass = '1';
$query = "INSERT INTO shoutbox (msgid, user, message, date, userid) VALUES (NULL, 'MaDHOUS3', ':hi: New Member: $wantusername', '".get_date_time()."', '0')";
mysql_query($query);
$ret = mysql_query("INSERT INTO users (username, password, secret, email, status, added, age, country, gender, client, stylesheet, language, class) VALUES (" .
implode(",", array_map("sqlesc", array($wantusername, $wantpassword, $secret, $email, $status, get_date_time(), $age, $country, $gender, $client, $site_config["default_theme"], $site_config["default_language"], $signupclass))).")");
// SMF 1.1.8 Intregration
createUser($id, $wantusername, $email, $wantpassword);
//
$id = mysql_insert_id();
$psecret = md5($secret);
$thishost = $_SERVER["HTTP_HOST"];
$thisdomain = preg_replace('/^www\./is', "", $thishost);
//ADMIN CONFIRM
if ($site_config["ACONFIRM"]) {
$body = "Your account at ".$site_config['SITENAME']." has been created.\n\nYou will have to wait for the approval of an admin before you can use your new account.\n\n".$site_config['SITENAME']." Admin";
}else{//NO ADMIN CONFIRM, BUT EMAIL CONFIRM
$body = "Your account at ".$site_config['SITENAME']." has been : APPROVED\n\nTo confirm your user registration, you have to follow this link:\n\n ".$site_config['SITEURL']."/account-confirm.php?id=$id&secret=$psecret\n\nAfter you do this, you will be able to use your new account.\n\n If you fail to do this, your account will be deleted within a few days.\n\n".$site_config['SITENAME']." Admin";
}
if ($site_config["CONFIRMEMAIL"]){ //email confirmation is on
ini_set("sendmail_from", "");
mail($email, "Your ".$site_config['SITENAME']." User Account", $body, "From: ".$site_config['SITENAME']." <".$site_config['SITEEMAIL'].">");
header("Refresh: 0; url=account-confirm-ok.php?type=signup&email=" . urlencode($email));
}else{ //email confirmation is off
header("Refresh: 0; url=account-confirm-ok.php?type=noconf");
}
//send pm to new user
if ($site_config["WELCOMEPMON"]){
$dt = sqlesc(get_date_time());
$msg = sqlesc($site_config["WELCOMEPMMSG"]);
mysql_query("INSERT INTO messages (sender, receiver, added, msg, poster) VALUES(0, $id, $dt, $msg, 0)");
}
die;
}
}//end takesignup
stdhead("Signup");
begin_frame("Signup");
?>
<? echo "" . COOKIES . "";?>
<p>
<form method="post" action="account-signup.php?takesignup=1">
<table cellSpacing="0" cellPadding="2" border="0" >
<tr>
<td>Username: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="text" size="40" name="wantusername" /></td>
</tr>
<tr>
<td>Password: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="password" size="40" name="wantpassword" /></td>
</tr>
<tr>
<td>Confirm: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="password" size="40" name="passagain" /></td>
</tr>
<tr>
<td>Email: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="text" size="40" name="email"/></td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" size="40" name="age" maxlength="3" /></td>
</tr>
<tr>
<td>Date Of Birth:</td>
<td>Day : <select name="day">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
<option>16</option>
<option>17</option>
<option>18</option>
<option>19</option>
<option>20</option>
<option>21</option>
<option>22</option>
<option>23</option>
<option>24</option>
<option>25</option>
<option>26</option>
<option>27</option>
<option>28</option>
<option>29</option>
<option>30</option>
<option>31</option>
</select>
Month : <select name="month">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
</select>
Year : <select name="year">
<option>2009</option>
<option>2008</option>
<option>2007</option>
<option>2006</option>
<option>2005</option>
<option>2004</option>
<option>2003</option>
<option>2002</option>
<option>2001</option>
<option>2000</option>
<option>1999</option>
<option>1998</option>
<option>1997</option>
<option>1996</option>
<option>1995</option>
<option>1994</option>
<option>1993</option>
<option>1992</option>
<option>1991</option>
<option>1990</option>
<option>1989</option>
<option>1988</option>
<option>1987</option>
<option>1986</option>
<option>1985</option>
<option>1984</option>
<option>1983</option>
<option>1982</option>
<option>1981</option>
<option>1980</option>
<option>1979</option>
<option>1978</option>
<option>1977</option>
<option>1976</option>
<option>1975</option>
<option>1974</option>
<option>1973</option>
<option>1972</option>
<option>1971</option>
<option>1970</option>
<option>1969</option>
<option>1968</option>
<option>1967</option>
<option>1966</option>
<option>1965</option>
<option>1964</option>
<option>1963</option>
<option>1962</option>
<option>1961</option>
<option>1960</option>
<option>1959</option>
<option>1958</option>
<option>1957</option>
<option>1956</option>
<option>1955</option>
<option>1954</option>
<option>1953</option>
<option>1952</option>
<option>1951</option>
<option>1950</option>
<option>1949</option>
<option>1948</option>
<option>1947</option>
<option>1946</option>
<option>1945</option>
<option>1944</option>
<option>1943</option>
<option>1942</option>
<option>1941</option>
<option>1940</option>
<option>1939</option>
<option>1938</option>
<option>1937</option>
<option>1936</option>
<option>1935</option>
<option>1934</option>
<option>1933</option>
<option>1932</option>
<option>1931</option>
<option>1930</option>
<option>1929</option>
<option>1928</option>
<option>1927</option>
<option>1926</option>
<option>1925</option>
<option>1924</option>
<option>1923</option>
<option>1922</option>
<option>1921</option>
<option>1920</option>
<option>1919</option>
<option>1918</option>
<option>1917</option>
<option>1916</option>
<option>1915</option>
<option>1914</option>
<option>1913</option>
<option>1912</option>
<option>1911</option>
<option>1910</option>
<option>1909</option>
<option>1908</option>
<option>1907</option>
<option>1906</option>
<option>1905</option>
<option>1904</option>
<option>1903</option>
</select>
</td>
</tr>
<tr>
<td>Country:</td>
<td>
<select name="country" size="1">
<?php
$countries = "<option value=\"0\">---- None selected ----</option>\n";
$ct_r = mysql_query("SELECT id,name,domain from countries ORDER BY name") or die;
while ($ct_a = mysql_fetch_array($ct_r)) {
$countries .= "\t\t\t\t\t\t<option value=\"$ct_a[id]\"";
if ($dom == $ct_a["domain"])
$countries .= " SELECTED";
$countries .= ">$ct_a[name]</option>\n";
}
?>
<?=$countries ?>
</select>
</td>
</tr>
<tr>
<td>Gender:</td>
<td>
<input type="radio" name="gender" value="Male">Male
<input type="radio" name="gender" value="Female">Female
</td>
</tr>
<tr>
<td>Preferred BitTorrent Client:</td>
<td><input type="text" size="40" name="client" maxlength="20" /></td>
</tr>
<tr>
<td>I Would Like To Recieve Newsletters:</td>
<td>
<input type="radio" name="option" value="yes">Yes
<input type="radio" name="option" value="No">No
</td>
</tr>
<br>
<tr>
<td>I Have Read And Understand The Disclaimer:</td>
<td><INPUT TYPE=CHECKBOX NAME="disclaimer"></td>
</tr>
<tr>
<td>Im Am At least The Age Of 18:</td>
<td><INPUT TYPE=CHECKBOX NAME="age"></td>
</tr>
<tr>
<td>I Have Read The Rules:</td>
<td><INPUT TYPE=CHECKBOX NAME="rules"></td>
</tr>
<tr>
<td align="middle" colSpan="2">
<input type="submit" value="Sign Up" />
</td>
</tr>
</table>
</form>
<?
end_frame();
stdfoot();
?>
Here's your problem:
function createUser($wantusername, $email, $wantpassword){
createUser($id, $wantusername, $email, $wantpassword);
You are telling the createUser function that:
$id -> $wantusername
$wantusername -> $email
$email -> $wantpassword
$wantpassword -> null
The order of your variables needs to match. There is absolutely no use for the $id variable in the function call.
ah yes lol i was gna see if i could make them have same id in both my site and forum to make life easier when deleting a user
i will test this
nope it still says incorrect password. i have recongized that the smf password field in database is same size as if i signup on the main website.
but when i use the same password on my site its same as where ive used it before lol im confused, wouldnt it jus be easier for me to replace the smfs hashing with same as myn??
What is myn?
What does your code in both files look like now?
here are the two files....
<?php
function createUser($wantusername, $email, $wantpassword){
global $db_name, $db_prefix, $sourcedir, $boarddir;
require_once ("forum/SSI.php");
// Set the options needed for registration.
$regOptions = array(
'interface' => 'guest',
'username' => $wantusername,
'email' => $email,
'password' => sha1(strtolower($wantusername) . un_htmlspecialchars($wantpassword)),
'password_check' => sha1(strtolower($wantusername) . un_htmlspecialchars($wantpassword)),
'check_reserved_name' => false,
'check_password_strength' => false,
'check_email_ban' => true,
'send_welcome_email' => false,
'require' => 'nothing',
'extra_register_vars' => array(),
'theme_vars' => array(),
);
if (isset($_POST['default_options']))
$_POST['options'] = isset($_POST['options']) ? $_POST['options'] + $_POST['default_options'] : $_POST['default_options'];
$regOptions['theme_vars'] = isset($_POST['options']) && is_array($_POST['options']) ? $_POST['options'] : array();
require_once($sourcedir . '/Subs-Members.php');
$memberID = registerMember($regOptions);
mysql_select_db($config["db_database"]);
}
?>
And The Signup Page .....
<?php
require_once("backend/functions.php");
require_once("backend/smf.php");
dbconn();
//invite only check
if ($site_config["INVITEONLY"]){
show_error_msg("Invite only", "<br><br><center>Sorry this site has disabled user registration, the only way to register is via a invite from a existing member.<br><br></center>",1);
}
//get max members, and check how many users there is
$numsitemembers = get_row_count("users");
if ($numsitemembers >= $site_config["maxsiteusers"])
show_error_msg("Sorry...", "The site is full!<br>The limit of ".number_format($site_config["maxsiteusers"])." users have been reached.<br>HOWEVER, user accounts expire all the time so please check back again later!<BR><BR>There is currently ".number_format($numsitemembers)." members",1);
if ($takesignup == "1"){
$message == "";
function validusername($username) {
$allowedchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for ($i = 0; $i < strlen($username); ++$i)
if (strpos($allowedchars, $username[$i]) === false)
return false;
return true;
}
//Setup Error Messages
if (empty($wantpassword) || empty($email) || empty($wantusername))
$message = "Don't leave any required field blank.";
if (strlen($wantusername) > 12)
$message = "Sorry, username is too long (max is 12 chars)";
if ($wantpassword != $passagain)
$message = "The passwords didn't match! Must've typoed. Try again.";
if (strlen($wantpassword) < 6)
$message = "Sorry, password is too short (min is 6 chars)";
if (strlen($wantpassword) > 40)
$message = "Sorry, password is too long (max is 40 chars)";
if ($wantpassword == $wantusername)
$message = "Sorry, password cannot be same as user name.";
if (!validemail($email))
$message = "That doesn't look like a valid email address.";
if (!validusername($wantusername))
$message = "Invalid username.";
if ($message == "") {
//check email isnt banned
$maildomain = (substr($email, strpos($email, "@")+1));
$a = (@mysql_fetch_row(@mysql_query("select count(*) from email_bans where mail_domain='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is Banned All Been A Member And Banned.";
$a = (@mysql_fetch_row(@mysql_query("select count(*) from email_bans where mail_domain='$maildomain'"))) or die(mysql_error());if ($a[0] != 0)
$message = "The e-mail address $email is Banned Due To Being A Free Provider Address.";
// check if email addy is already in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where email='$email'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The e-mail address $email is already in use.";
//check username isnt in use
$a = (@mysql_fetch_row(@mysql_query("select count(*) from users where username='$wantusername'"))) or die(mysql_error());
if ($a[0] != 0)
$message = "The username $wantusername is already in use.";
$secret = mksecret(); //generate secret field
$wantpassword = md5($wantpassword);//md5 hash the password
}
if ($message != "")
show_error_msg("Signup Failed", $message,1);
if ($message == "") {
if ($site_config["CONFIRMEMAIL"]){//req confirm email true/false
$status = "pending";
}else{
$status = "confirmed";
}
//make first member admin
if ($numsitemembers == '0')
$signupclass = '7';
else
$signupclass = '1';
$query = "INSERT INTO shoutbox (msgid, user, message, date, userid) VALUES (NULL, 'MaDHOUS3', ':hi: New Member: $wantusername', '".get_date_time()."', '0')";
mysql_query($query);
$ret = mysql_query("INSERT INTO users (username, password, secret, email, status, added, age, country, gender, client, stylesheet, language, class) VALUES (" .
implode(",", array_map("sqlesc", array($wantusername, $wantpassword, $secret, $email, $status, get_date_time(), $age, $country, $gender, $client, $site_config["default_theme"], $site_config["default_language"], $signupclass))).")");
// SMF 1.1.8 Intregration By DJHOWARTH
createUser($wantusername, $email, $wantpassword);
//
$id = mysql_insert_id();
$psecret = md5($secret);
$thishost = $_SERVER["HTTP_HOST"];
$thisdomain = preg_replace('/^www\./is', "", $thishost);
//ADMIN CONFIRM
if ($site_config["ACONFIRM"]) {
$body = "Your account at ".$site_config['SITENAME']." has been created.\n\nYou will have to wait for the approval of an admin before you can use your new account.\n\n".$site_config['SITENAME']." Admin";
}else{//NO ADMIN CONFIRM, BUT EMAIL CONFIRM
$body = "Your account at ".$site_config['SITENAME']." has been : APPROVED\n\nTo confirm your user registration, you have to follow this link:\n\n ".$site_config['SITEURL']."/account-confirm.php?id=$id&secret=$psecret\n\nAfter you do this, you will be able to use your new account.\n\n If you fail to do this, your account will be deleted within a few days.\n\n".$site_config['SITENAME']." Admin";
}
if ($site_config["CONFIRMEMAIL"]){ //email confirmation is on
ini_set("sendmail_from", "");
mail($email, "Your ".$site_config['SITENAME']." User Account", $body, "From: ".$site_config['SITENAME']." <".$site_config['SITEEMAIL'].">");
header("Refresh: 0; url=account-confirm-ok.php?type=signup&email=" . urlencode($email));
}else{ //email confirmation is off
header("Refresh: 0; url=account-confirm-ok.php?type=noconf");
}
//send pm to new user
if ($site_config["WELCOMEPMON"]){
$dt = sqlesc(get_date_time());
$msg = sqlesc($site_config["WELCOMEPMMSG"]);
mysql_query("INSERT INTO messages (sender, receiver, added, msg, poster) VALUES(0, $id, $dt, $msg, 0)");
}
die;
}
}//end takesignup
stdhead("Signup");
begin_frame("Signup");
?>
<? echo "" . COOKIES . "";?>
<p>
<form method="post" action="account-signup.php?takesignup=1">
<table cellSpacing="0" cellPadding="2" border="0" >
<tr>
<td>Username: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="text" size="40" name="wantusername" /></td>
</tr>
<tr>
<td>Password: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="password" size="40" name="wantpassword" /></td>
</tr>
<tr>
<td>Confirm: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="password" size="40" name="passagain" /></td>
</tr>
<tr>
<td>Email: <font class="small"><font color="#FF0000">*</font></td>
<td><input type="text" size="40" name="email"/></td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" size="40" name="age" maxlength="3" /></td>
</tr>
<tr>
<td>Date Of Birth:</td>
<td>Day : <select name="day">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
<option>16</option>
<option>17</option>
<option>18</option>
<option>19</option>
<option>20</option>
<option>21</option>
<option>22</option>
<option>23</option>
<option>24</option>
<option>25</option>
<option>26</option>
<option>27</option>
<option>28</option>
<option>29</option>
<option>30</option>
<option>31</option>
</select>
Month : <select name="month">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
</select>
Year : <select name="year">
<option>2009</option>
<option>2008</option>
<option>2007</option>
<option>2006</option>
<option>2005</option>
<option>2004</option>
<option>2003</option>
<option>2002</option>
<option>2001</option>
<option>2000</option>
<option>1999</option>
<option>1998</option>
<option>1997</option>
<option>1996</option>
<option>1995</option>
<option>1994</option>
<option>1993</option>
<option>1992</option>
<option>1991</option>
<option>1990</option>
<option>1989</option>
<option>1988</option>
<option>1987</option>
<option>1986</option>
<option>1985</option>
<option>1984</option>
<option>1983</option>
<option>1982</option>
<option>1981</option>
<option>1980</option>
<option>1979</option>
<option>1978</option>
<option>1977</option>
<option>1976</option>
<option>1975</option>
<option>1974</option>
<option>1973</option>
<option>1972</option>
<option>1971</option>
<option>1970</option>
<option>1969</option>
<option>1968</option>
<option>1967</option>
<option>1966</option>
<option>1965</option>
<option>1964</option>
<option>1963</option>
<option>1962</option>
<option>1961</option>
<option>1960</option>
<option>1959</option>
<option>1958</option>
<option>1957</option>
<option>1956</option>
<option>1955</option>
<option>1954</option>
<option>1953</option>
<option>1952</option>
<option>1951</option>
<option>1950</option>
<option>1949</option>
<option>1948</option>
<option>1947</option>
<option>1946</option>
<option>1945</option>
<option>1944</option>
<option>1943</option>
<option>1942</option>
<option>1941</option>
<option>1940</option>
<option>1939</option>
<option>1938</option>
<option>1937</option>
<option>1936</option>
<option>1935</option>
<option>1934</option>
<option>1933</option>
<option>1932</option>
<option>1931</option>
<option>1930</option>
<option>1929</option>
<option>1928</option>
<option>1927</option>
<option>1926</option>
<option>1925</option>
<option>1924</option>
<option>1923</option>
<option>1922</option>
<option>1921</option>
<option>1920</option>
<option>1919</option>
<option>1918</option>
<option>1917</option>
<option>1916</option>
<option>1915</option>
<option>1914</option>
<option>1913</option>
<option>1912</option>
<option>1911</option>
<option>1910</option>
<option>1909</option>
<option>1908</option>
<option>1907</option>
<option>1906</option>
<option>1905</option>
<option>1904</option>
<option>1903</option>
</select>
</td>
</tr>
<tr>
<td>Country:</td>
<td>
<select name="country" size="1">
<?php
$countries = "<option value=\"0\">---- None selected ----</option>\n";
$ct_r = mysql_query("SELECT id,name,domain from countries ORDER BY name") or die;
while ($ct_a = mysql_fetch_array($ct_r)) {
$countries .= "\t\t\t\t\t\t<option value=\"$ct_a[id]\"";
if ($dom == $ct_a["domain"])
$countries .= " SELECTED";
$countries .= ">$ct_a[name]</option>\n";
}
?>
<?=$countries ?>
</select>
</td>
</tr>
<tr>
<td>Gender:</td>
<td>
<input type="radio" name="gender" value="Male">Male
<input type="radio" name="gender" value="Female">Female
</td>
</tr>
<tr>
<td>Preferred BitTorrent Client:</td>
<td><input type="text" size="40" name="client" maxlength="20" /></td>
</tr>
<tr>
<td>I Would Like To Recieve Newsletters:</td>
<td>
<input type="radio" name="option" value="yes">Yes
<input type="radio" name="option" value="No">No
</td>
</tr>
<br>
<tr>
<td>I Have Read And Understand The Disclaimer:</td>
<td><INPUT TYPE=CHECKBOX NAME="disclaimer"></td>
</tr>
<tr>
<td>Im Am At least The Age Of 18:</td>
<td><INPUT TYPE=CHECKBOX NAME="age"></td>
</tr>
<tr>
<td>I Have Read The Rules:</td>
<td><INPUT TYPE=CHECKBOX NAME="rules"></td>
</tr>
<tr>
<td align="middle" colSpan="2">
<input type="submit" value="Sign Up" />
</td>
</tr>
</table>
</form>
<?
end_frame();
stdfoot();
?>
what i meant by above was i installed smf and it made my account and i created a user on my site with the same password and the hash was the same as the my passwords hash for the admin account.
any ideas anyone??
AFTER changing the code, did you delete the user in BOTH SMF and your system, and try registering again?
yep i tried after i changed it if u not busy try it your self
http://www.madhous3.co.uk (http://www.madhous3.co.uk)
and the forum
http://www.madhous3.co.uk/forum/ (http://www.madhous3.co.uk/forum/)
i tried resetting the password via smf and that worked i could login afterwards...
so that means on my site if i had activation on i could try and combine it to send both but if ive noticed not everyone uses a proper email address so that would be a bad idea lmao
Change your code in the first file above to this:
<?php
function createUser($wantusername, $email, $wantpassword){
global $db_name, $db_prefix, $sourcedir, $boarddir;
require_once ("forum/SSI.php");
echo $wantpassword;
exit;
// Set the options needed for registration.
$regOptions = array(
When you try to register a user, copy the result from the page, and paste it in a post here.
02532bdc1420c1aab2c5c7699cdb4cb5
Alright. Then that answers the question that I had in this post:
Quote from: Orstio on February 23, 2009, 07:49:30 PM
That'll be the problem, then.
You'll probably want to echo $wantpassword to find out what value it is getting, and compare to the value entered in the database.
Except for the fact that it is a different answer than you gave me the first time.
You're going to have to use this:
'password' => $wantpassword,
'password_check' => $wantpassword,Unless you have some way of passing the unhashed password to the createUser function instead.
erm...
the first time i echod i had the regoptions aswell thats probly why...
is their a way i can nick smfs hashing system?? and replace my md5 parts with the smf parts e.g
account-recover, account-login, account-signup
You can write your MD5 hash directly to SMF. SMF won't have any problem with your MD5 hash.
how do u mean?
could u show me a little example maybe?
You already have an example. Your code is putting a MD5 hash into $wantpassword before passing it to createUser().
Perhaps you are confused about the chain of events we've gone through?
You had the wrong values being passed to createUser(), as per this post:
Quote from: Orstio on February 25, 2009, 07:22:54 PM
Here's your problem:
function createUser($wantusername, $email, $wantpassword){
createUser($id, $wantusername, $email, $wantpassword);
You are telling the createUser function that:
$id -> $wantusername
$wantusername -> $email
$email -> $wantpassword
$wantpassword -> null
The order of your variables needs to match. There is absolutely no use for the $id variable in the function call.
That was what was causing you the problem in the first place. Your password was always wrong because you were putting the email address in the password field.
Now that has been fixed, and now we know that the MD5 hash is actually being passed to the createUser function, you can just write that MD5 hash to the SMF password field, and all will work as expected.
do u mean
password = '$wantpassword = md5($wantpassword);'
passwordcheck = '$wantpassword = md5($wantpassword);'
Your code already does that before it passes $wantpassword to createUser(). If you do it again, you will get the wrong hash.
still incorrect password lol
<?php
function createUser($wantusername, $email, $wantpassword){
global $db_name, $db_prefix, $sourcedir, $boarddir;
require_once ("forum/SSI.php");
// Set the options needed for registration.
$regOptions = array(
'interface' => 'guest',
'username' => $wantusername,
'email' => $email,
'password' => $wantpassword,
'password_check' => $wantpassword,
'check_reserved_name' => false,
'check_password_strength' => false,
'check_email_ban' => true,
'send_welcome_email' => false,
'require' => 'nothing',
'extra_register_vars' => array(),
'theme_vars' => array(),
);
if (isset($_POST['default_options']))
$_POST['options'] = isset($_POST['options']) ? $_POST['options'] + $_POST['default_options'] : $_POST['default_options'];
$regOptions['theme_vars'] = isset($_POST['options']) && is_array($_POST['options']) ? $_POST['options'] : array();
require_once($sourcedir . '/Subs-Members.php');
$memberID = registerMember($regOptions);
mysql_select_db($config["db_database"]);
}
?>
Make sure you delete the user from both systems before attempting to register and login. This code will not work retroactively on already-existing users.
yeh i had to make the passwords plain
so i jus moved it up the page and renamed $wantpassword = md5($wantpassword); to $md5 lmao cheers i ant been on in ages coz i been looking at login and logout i dint understand it could u help plz m8
Orstio I am completely lost with how to get my CMS integrated with SMF.
Could you tell me which file goes where and which code goes in the files.
I use MODx CMS that has its own login system and authentication and I would like to some how allow my users to sign in to the CMS and SMF with one sign in. I simply want to work on the login part for now to get my head round how this works.
I have read for days and still don't understand how it all works. Where should the integrate.php file be, do I need SSI or smf_api.php to get it working etc...
I'm have SMF 2.0 rc1.1 installed. I just can't seem to grasp how it all works so a little help would be great.
Thanks.
I think MODx already has an integration: http://modxcms.com/extras.html?view=package/view&package=419
Thanks for the reply... It doesn't actually work.
I have tried it with several versions of modx and smf and it simply doesn't work and it's been noted in the modx forum and accepted it doesn't haha.
Basically I have an SMF forum with 1500 members already signed up and there is 50 members signed up to the modx site. The modx site is used for all the business for members only but I would like the users to be able go from the modx site to the forum without having to sign in twice.
Modx uses standard MD5 for passwords, what would be the best way to allow seamless browsing from the modx side to the forum?
Thanks for the quick answer.
The easiest way would be to use the integrate_pre_include and integrate_verify_user hooks.
I know it's a lot to ask but could you give me an illustrated example of the code and where it goes both in SMF and what needs to be on the modx side (any php scripts). I'm a beginner with SMF code and integration and I know a little about how modx runs. I was up till 3.30am reading what I need to do and I just don't seem to grasp the idea. :'(
You don't need to touch any SMF code. That is why there are integration hooks.
I don't know any more of how MODx works than you do.
modx is installed in the root of my server (i have a dedicated server) /home/mysite/www/ and I have SMF installed in /home/mysite/www/forum
Ok so I would create a file, i'll call it integrate.php and I will put this in the forum directory. I would put the hook information in this file?
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_pre_include' => 'integration.php',
'integrate_verify_user' => 'UserID',
)));
function UserID ()
{
$ID_MEMBER = (int) $_COOKIE['USERID'];
return $ID_MEMBER;
}
)));
The cookie with the user id is created when the user logs in to the CMS.
I would then call this file in the SMF index.php
require_once('/integrate.php');
Then create a login page in my CMS
<form action="http://www.mysite/forum/index.php?action=login2" method="post">
<input type="text" id="username" name="username" >
<input type="password" name="password" id="password">
<button type="submit" id="submit">Go!</button>
</form>
Is this way of the beaten track of what I need to do?
Close.
Do you believe your MODx userid and SMF ID_MEMBER are going to be exactly the same? You'll probably need to do a lookup query or two to get the right id number in SMF.
When you require the file, leave out the slash. You're requiring a file in the same directory, it might get confused with the slash.
The login page is completely useless. THe whole point in using the integrate_verify_user hook is to avoid needing to login a second time, which means that having a secondary form for logging in is useless.
I don't mind manually setting the ID in the modx database to match the SMF id. Prefer not to do that but I am trying to get the basics working then build on that idea. I'm learning so if I can get the fundamentals of getting the user logged in to both systems at least, I can work on it slowly.
Would the user be best to sign in via SMF or MODx for this to work the way I wish?
MODx
Ok... so I sign in to MODx and the cookie USERID is set with the ID of the user in MODx. If I then go to the SMF forum this cookie will be checked and the userid is taken and matched up against the userid in the SMF database. If there is a match then the user is signed in.
EDIT
I just tried it and it works!
Orstio many many thanks for your patience and help. I hard coded the cookie to match the ID of the SMF admin and it worked so time to do some coding to set the USERID according to the user logging in, validate it against a verification key idea to keep things more secure and that should hopefully get me closer to where I want to be.
Thanks again, Ross
Well it worked for a few minutes and isn't now LOL! I guess I will check again tomorrow.
Does your MODx cookie time out?
The cookie was dieing prematurely but I think I have sorted it now... think!
What I have noticed, I have yshout integrated in to my forum and members can only leave messages if they are logged in. However, even though I have logged in via MODx and can access my account in SMF and the admin area, I can't post in the shout. I understand that the shoutbox probably has a further verification method, is there a way round the way that I have signed in via MODx to mimic the SMF login that would allow users to use the shoutbox? Or is it likely I would need to trawl through the code of the shoutbox to find where and what is verifying a logged in user?
The shoutbox I am using is this one. http://www.simplemachines.org/community/index.php?topic=137508.5420;topicseen
Does the shoutbox open in an iframe? If it does, chances are it is trying to validate with a SMF cookie, which does not exist with your integrated login.
No it doesn't use iframes. When I arrive at the forum page it briefly shows that I am signed in and can post in the shout then it says I can not shout as I am not signed in... if I navigate to another page in SMF it the signs me out. The cookies are still about with the correct codes. What could be killing the session? Perhaps the code I have included in my idea below is at fault?
On a side note I wonder if you could tell me if my idea is safe / secure to use?
The user logs in to modx, using a system event (onlogin) 2 cookies are created. One is called USERID the other VERIFY. When the user signs in to modx a string of numbers and letters is then past to the database in both modx and SMF and stored as VerificationKey. The 2 cookies that were created hold the userID, the other holds the 20 digit long VerificationKey. When the user goes to SMF, the cookies are checked against the SMF database to match the userID and then the VerificationKey. If both match up to one user they are verified and logged in. I tested the cookie settings by changing the userID in the USERID cookie to a different integer and since the verification key does not match this user, there is no access to any of the user accounts in SMF. Would this be counted as fairly secure?
In my integrate.php I have this code.
if (!isset ($_COOKIE['USERID'])){
echo "";}
else{
$userID = $_COOKIE['USERID'];
$verifycookie = $_COOKIE['VERIFY'] ;
$dbhost = 'xxx';
$dbuser = 'xxx';
$dbpass = 'xxx';
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
$dbname = 'community';
mysql_select_db($dbname);
$query = "SELECT id_member,VerificationKey FROM smf_members WHERE id_member=$userID";
$result = mysql_query($query) ;
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$verifyme = $row['VerificationKey'];
}
$myVerify = $verifyme ;
if($verifycookie == $myVerify)
{
define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_pre_include' => 'integration.php',
'integrate_verify_user' => 'UserID',
)));
function UserID ()
{
$ID_MEMBER = (int) $_COOKIE['USERID'];
return $ID_MEMBER;
}
}
else{
echo"ERROR";
}
}
bare in mind I am a novice with PHP so my idea and code might be completely rubbish! :P
EDIT
I noticed that if I go to http://domain I am signed out, but if I am at http://www.domain it will say I am signed in but I still can not use the shoutbox.
QuoteI noticed that if I go to http://domain I am signed out, but if I am at http://www.domain it will say I am signed in but I still can not use the shoutbox.
Turn on subdomain independent cookies in SMF?
Also, to be on the safe side, make sure you are accessing your site at the URL specified in the CMS and forum configuration. That means, if you installed at http://www.site.com, do not access at http://site.com. Make sure to use the www if that's what's in the configuration. If there is no www in the configuration, then make sure not to use it.
Hello,
Local storage is off and Use subdomain independent cookies is on.
I am using an htaccess file to redirect users who try to use http://mysite to use www.
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.site\.com [NC]
RewriteRule (.*) http://www.site.com/$1 [R=301,L]
This wasn't working at first with SMF as it was just refreshing the page when a user tried to sign in but now I modified the url in the SMF settings.php to use www. it's working but still no permissions to use the shout.
I noticed that all my cookies are set to use "/" for the path which is what I want but the shout is using /forum/, would this cause the issue of not being able to post? When the page loads I have a split second of being able to post in the shout but it is then quickly disabled so it is giving permission then taking it away. Using firebug I see that all it does it puts disabled="disabled" in to the input form to stop users posting that are not signed in, If I delete this in firebug I can post in the shout.
5 hours sleep a night the last 3 days lol... I'm determined to get this working! ;D
Thanks for your help so far, it really is appreciated.
This:
QuoteI am using an htaccess file to redirect users who try to use http://mysite to use www.
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.site\.com [NC]
RewriteRule (.*) http://www.site.com/$1 [R=301,L]
Combined with this:
QuoteI noticed that all my cookies are set to use "/" for the path
Is always going to give you problems. Cookies can't set if they are redirected. So, .htaccess redirects are nothing but trouble.
OK, I disabled the htaccess file and it's not made any difference with the shoutbox.
The usage of the shoutbox and working on the logout function is pretty much all I have to get working now.
An example of my cookie startup code is
setcookie("USERID","$cookieKey",time()+604800, "/", "", 0);
Should I try without the "/" ? I keep going round in circles trying to figure out what the issue is as I can access the admin area etc no problem.
I will keep working on it but so far it's been a non starter.
Hey, I have tried everything in my arsenal and I can't figure out why the shoutbox is acting up this way.
As I said, when I sign in via modx and load up the forum, the shout box very briefly allows me access to post but then it quickly changes to say I'm not logged in. However I can access everything as if I am signed in so it's something specific with the shoutbox.
I have posted in the forum for the shoutbox but it looks like the creator isn't about lately so I can' get help there.
The only difference between signing in to the forum from modx to the native SMF login form is the cookie called SMFcookie11 that I can see.
I have setup a test account for both modx and SMF if anyone is able to possibly give me an idea what is causing the shoutbox to disable.
sign in to modx here (it's not very good looking as I'm upgrading the whole site) http://www.err-clan.com there is a simple signin box on the right side.
Username : testac
Password : testing
once you sign in, there is a link to the test forum on the right bar. This will take you to the test forum that is under construction. You will see that you can edit your profile, add posts etc but you can not use the shoutbox. Load the page, stop it completely loading and you will see you have access to the shoutbox inputs and can post then try reloading the page completely, you will then see it quickly disables once the page is completed.
Any help with this will be much appreciated.
Ross
Yes, it seems to be trying to read specifically from the SMF cookie instead of just checking for online status using $context or $user_info.
As I said, I tried everything possible (that I know) to try get that working and I just don't know enough about coding to get it working.
There is a few lines of coding relating to cookies but I just don't see what it is that allows access then not. Strange that it allows it briefly. I will keep trying.
hi, my website doesnt have a cms, and i wouldnt use ssi because my existent login system is already set. but i need to intergrate smf into it.
passwords for my site are usually hashed. so how would i go about the hooks for creating the smf sessions?
Trying to get my head around this concept.
So this is to authenticate the user against SMF's database (and also login to SMF)? You effectively bypass the CMS (or whatever you're using) login and directly set the CMS session.
If so, does the CMS and SMF member database have to match? Im guessing you dont even need the CMS member database, but that would require you to hook every single member function like login, log out, change pass, change email etc.
QuoteIf so, does the CMS and SMF member database have to match?
No. You just correlate that in your hook function.
QuoteIm guessing you dont even need the CMS member database, but that would require you to hook every single member function like login, log out, change pass, change email etc.
It works best to have both databases. But yes, you do need to hook all of the functionality.
Hi!
I have a selfbuild CMS which uses SMF as forum. Now I want to create a user system at the frontpage by using SMF. For example I would like the user to login and post a reply on a news article.
But now my question. It looks like the hooks are build so the hooked functions will be called by SMF, but how can I use this to make a user login on my CMS by using his account information from SMF?
I couldn't really find an awnser in the iGamingCMS.
Thanks in advance!
You don't need the hooks for that. Just SSI. Do a search for SSI.php.
Hi,
I've also been struggling with integration hooks :-[. I've been trawling these forums for an answer but to no avail.
Basically I'm integrating the forum's user authentication with a client's website that already has an existing login system. I'm using integrate_verify_user since (eventually) I plan on removing the forum's login and registration all together. The existing site has been poorly coded by another designer which hasn't helped.
Everything works fine initially. Once the user has logged into the existing site, they can navigate to the forum, where they will be automatically logged in and registered (if necessary). However, this does not seem to last until the next page. The existing site's session variables are no more, and SMF doesn't appear to recognise that it just logged someone in. I can't for the life of me figure out how to get around this.
The forum is in a seperate directory to the existing site (i.e. mydomain.com/forum) and I'm using the following files...
Firstly, I've put an include into SMF's index.php (/forum/index.php):
// And important includes.
require_once($sourcedir . '/QueryString.php');
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Errors.php');
require_once($sourcedir . '/Load.php');
require_once($sourcedir . '/Security.php');
//AND THE INTEGRATION INCLUDE FOR BID4TACKLE
require 'integrate.php';
// Using an old version of PHP?
if (@version_compare(PHP_VERSION, '4.2.3') != 1)
require_once($sourcedir . '/Subs-Compat.php');
And here's my include... (forum/integrate.php)
<?PHP
session_start();
define('SMF_INTEGRATION_SETTINGS', serialize(array( //Starting the hook system
'integrate_verify_user' => 'verfiyUser',
)));
function verfiyUser() {
//Is a user logged into Bid4Tackle by Session?
if(empty($_SESSION['username'])) {
//Is a user logged into Bid4Tackle by Cookie?
if (!isset($_COOKIE['BFTusername'])) {
return;
} else {
$bftUsername = $_COOKIE['BFTusername'];
};
} else {
$bftUsername = $_SESSION['username'];
};
//Check if user is an SMF member
$getSmfUser = mysql_query("SELECT ID_MEMBER FROM forum_members WHERE realName = '" . $bftUsername . "'");
if (mysql_num_rows($getSmfUser) >= 1) {
$smfUserRow = mysql_fetch_array($getSmfUser);
$smfUserID = $smfUserRow['ID_MEMBER'];
} else { //If not, add Bid4Tackle user to SMF member list
//Get user's Bid4Tackle account info
$getBftUser = mysql_query("SELECT * FROM user_registration WHERE user_name = '" . $bftUsername . "'");
if (mysql_num_rows($getBftUser) <= 0) {
return;
};
$row = mysql_fetch_array($getBftUser);
//Migrate user to SMFfor
$smfUserID = migrateToSMF($row['user_name'], $row['password'], $row['email']);
};
return $smfUserID;
};
function migrateToSMF($username, $password, $email){
$join_date = time();
mysql_query("
INSERT INTO forum_members
(memberName,
realName,
passwd,
emailAddress,
dateRegistered,
ID_POST_GROUP,
lngfile,
buddy_list,
pm_ignore_list,
messageLabels,
personalText,
websiteTitle,
websiteUrl,
location,
ICQ,
MSN,
signature,
avatar,
usertitle,
memberIP,
memberIP2,
secretQuestion,
additionalGroups)
VALUES
('$username',
'$username',
'$password',
'$email',
$join_date,
'4',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'')"
);
$memberID = mysql_insert_id();
mysql_query("UPDATE forum_log_activity SET registers = registers + 1 WHERE date ='" . date("Y-m-d") . "' LIMIT 1");
return $memberID;
}
?>
I'm at my wit's end and would really appreciate some help. Is my code correct? How do I get SMF to stay logged in?
Thanks
itscooper
Start by removing the session_start(). It has no use.
Does your other system use a cookie? It would probably be best to read from the cookie rather than the session. Not only does SMF ignore the PHP session (it uses a custom session handler), it also purges the session on certain events and repopulates it with only specific data to guard against session fixation exploits. So using the session as a means of communicating to SMF is inconsistent at best.
Thanks Orstio,
Well I thought that as well... so basically I redesigned the user authentication system so it would use cookies. But (and I really don't get this) exactly the same thing happens. Once I go onto the forum it says I'm logged in using a cookie. Next page it refuses to accept that the cookie exists (yet the cookie is still there with the right info in it).
I then decided to write my own database session system for the existing website like SMF has. It makes a record of of the session_id() and the user who's logged in. However (and I could have probably guessed this) the session_id() changes exactly when the $_SESSION variables disappear. (nb: This is all happening in a prepend file so it occurs on SMF pages as well)
I understand that SMF might want to erase the sessions, but don't get why my prepend file can't access cookies all of a sudden. :-[
I really haven't got a clue where to go next.
Cheers
ItsCooper
How are you setting the cookie?
>:( I'm an idiot!
It was nothing to do with the hooks. My original code would have worked fine.
You see my client's site has more than one domain (i.e. a .co.uk and a .com) which all point to the same website. I was testing on the .com but I accidentally set the forum to just use the .co.uk. So everytime I clicked a link on the forum, I would go over to the .co.uk which uses different sessions and cookies altogether!
I cannot believe I missed that. The hours I've wasted. :-[ At least it works now.
I'm extremely sorry for wasting your time Orstio. These hooks are excellent by the way!
Thanks for all your help
ItsCooper
A question if you please:
On an external site with separate software when the person registers using on the site I have set up a call that also registers the same person on SMF using SSI. That is done successfully.
My question, why isn't user logged on automatically via SSI the same as when they are when registering through SMF directly? Shouldn't a cookie be set when $regOptions is used?
I've used this to try and set a cookie but with no success:
[define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_verify_user' => 'integrate_verify_user',
)));
function integrate_verify_user() {
if($id_member) {
require_once('/community/Sources/LogInOut.php');
require_once('/community/Sources/Load.php');
require_once('/community/Sources/Subs-Auth.php');
setLoginCookie(8000000, $result[0]['id_member'], sha1($result[0]['password'].$result[0]['passwordSalt']));
return $result[0]['id_member'];
} else {
return false;
}
}/code]
Your function will always return false. $id_member is not global, and not defined anywhere.
OK so in this case I'm using the following what am I missing to get SMF to set the cookie in this process given the first Registration part works well:
global $context;
require_once('/community/SSI.php');
require_once('/community/Sources/Subs-Members.php');
$regOptions = array(
'interface' => 'guest',
'username' => $txtUserName,
'email' => $txtEmail,
'password' => $txtPassword,
'password_check' => $txtConfirmPassword,
'auth_method' => 'password',
'check_reserved_name' => true,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => false,
'require' => 'nothing',
'memberGroup' => 0,
'just_registered' => 1,
);
$id_member = registerMember($regOptions);
if (is_array($id_member))
die('Registration failed');
[define('SMF_INTEGRATION_SETTINGS', serialize(array(
'integrate_verify_user' => 'integrate_verify_user',
)));
function integrate_verify_user() {
if($id_member) {
require_once('/community/Sources/LogInOut.php');
require_once('/community/Sources/Load.php');
require_once('/community/Sources/Subs-Auth.php');
setLoginCookie(8000000, $result[0]['id_member'], sha1($result[0]['password'].$result[0]['passwordSalt']));
return $result[0]['id_member'];
} else {
return false;
}
}
I think you are very confused about the the ideas of registration and login.
Registration is what a user does to create their account. This is only done once per user.
Login is what the user does to use the account they created when they registered. This can be done an infinite number of times for the same account.
Registering is not logging in, and logging in is not registering.
In addition, your integrate_verify_user hook is never used. It needs to be defined BEFORE the call to SSI, which isn't going to work as you want because at that point, the user isn't even registered yet. THe integration hooks will not help you in any way with the method you are trying to accomplish.
So then I cannot use the SSI method to have the user registered and automatically logged in as it would when doing it from the regular SMF registration page?
I was trying to avoid having the person register using SMF and passing that info to the site's DB.
Yes you can, but the integration hooks are the wrong choice of methods to accomplish it.
Look in Register.php in the Register2() function to see how SMF accomplishes it.
Thanks for the direction. I guess you are referring to:
setLoginCookie(60 * $modSettings['cookieTime'], $memberID, sha1(sha1(strtolower($regOptions['username']) . $regOptions['password']) . substr($regOptions['register_vars']['passwordSalt'], 1, -1)));
Based on my code I inserted it like this:
$regOptions = array(
'interface' => 'guest',
'username' => $txtUserName,
'email' => $txtEmail,
'password' => $txtPassword,
'password_check' => $txtConfirmPassword,
'auth_method' => 'password',
'check_reserved_name' => true,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => false,
'require' => 'nothing',
'memberGroup' => 0,
'just_registered' => 1,
);
$id_member = registerMember($regOptions);
if (is_array($id_member))
die('Registration failed');
setLoginCookie(-1, $id_member, sha1(sha1(strtolower($regOptions['username']) . $regOptions['password']) . substr($regOptions['passwordSalt'], 1, -1)));
But not a go.
Oh!
That's because there's no password salt.
You don't have any code to set $regOptions['passwordSalt'].
That's true but would I have to querry the database for that? If I am sticking with SSI $regOptions then I'll need something like
'passwordSalt' => (but what)?
Or am I going wrong here. Thanks.
You need to use $regOptions['register_vars']['passwordSalt'].
I had that before and actually thought it was part of why it was not working. Adding it back did not help.
Here is my whole code for this:
global $context;
require_once('/community/SSI.php');
require_once('/community/Sources/Subs-Members.php');
$regOptions = array(
'interface' => 'guest',
'username' => $txtUserName,
'email' => $txtEmail,
'password' => $txtPassword,
'password_check' => $txtConfirmPassword,
'auth_method' => 'password',
'check_reserved_name' => true,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => false,
'require' => 'nothing',
'memberGroup' => 0,
'just_registered' => 1,
);
$id_member = registerMember($regOptions);
if (is_array($id_member))
die('Registration failed');
setLoginCookie(-1, $id_member, sha1(sha1(strtolower($regOptions['username']) . $regOptions['password']) . substr($regOptions['register_vars']['passwordSalt'], 1, -1)));
Can you try using a positive number for the cookie time?
Thank you so much that worked!
I wonder why "-1" did not? Shouldn't that not give an more or less indefinite cookie?
No, it gives a cookie that's already expired.
Thanks again.
Hi, I read the "guide to the SMF integration hooks" and it seems pretty straight forward, except for one thing:
Where or what stock PHP file edit or create to begin the process, in other words where do I create?
define('SMF_INTEGRATION_SETTINGS', .....
I got the idea that I didn't have to edit any stock PHP code and that it looks for a "optional hook" file that it will include if it exist, but that wasn't straight forward. Load.php appearts to look for SMF_INTEGRATION_SETTINGS before it applies 'integrate_pre_include'. I'm sure its simple and I just missed it.
Background:
If you can provide some guidance, it would be appreciate.
I'm the author of the WINSERVER (Wildcat! Interactive Net Server) intranet system, and we got some operators who wants to integrate SMF with WINSERVER. But only at the authentication level. Not replace it but add the hooks, so when they login or logout into either system, they are synchronzed.
So if they login via SMF, a hook will authenticate the user at WINSERVER. When he logs off, a hook will log him off WINSERVER. And vice versa. In addition, if the user registers with SMF, an account is also created at WINSERVER as well. In short, they are sychronized authentication wise on both software.
I did the same thing with another customer using InstantForum. It was almost two years, so I don't totally recall, but in that system, the hooking using optional "landing pages" so if /loginpage.asp existed, then it will display that. I used this optional page to authenticate against our winserver, when redirected back to loginpage.asp. Similar with the other landing pages for register, logout, etc.
Based on what I read so far with the guide, it appears this will be easier since we have a PHP_WILDCAT.DLL extension that ties into the servers session context management and with the hooks, I will be able to work with the DLL.
So basically, all I need to know is what comes first here, the egg or chicken - where do I define the settings for the hooks?
Thanks
Hector
You do it in your own file.
For your particular application, I would probably skip the SMF_INTEGRATION_SETTINGS and write the values directly to the settings table in the database. That way, integrate_pre_include can be the file you use for the code for all the other hooks.
Hi Orstio,
Please forgive me, I am 500% new to your software, but not to programming. "do it in your own file". Ok, but how does that file get integrated by SMF? Do I edit /index.php? /Settings.php?
When I give the "end product" to the operators, I want it plug and play. I don't wish to edit any stock files in SMF, unless that is what it takes.
I want to explore all methods, as you suggest with your expertise. But I have not yet learned the SMF framework, flow of php scripts, etc. So if the SMF_INTEGRATION_SETTINGs method is good enough to get me started, see some results, better understand the flow, then I can explore going more directy as you suggest, and I will if thats the better method.
I just need to get in the pool to get started. :)
What I am doing right now is adding this DEFINE to the top of the settings.php file. Is that ok?
Again, my preference is not to edit any of stock files because if the operators upgrades to new SMF versions, I don't want to get into version control issues.
Thanks
Hector
Adding it to index.php or settings.php should be fine then, yes.
What I was suggesting you do was add the variable=>value pairs to the smf_settings table instead of having the hardcoded SMF_INTEGRATION_SETTINGS. Both methods work, but the former requires no edits to the code.
Ok, Yes, I just read the Load.php code to see how it merged the optional SMF_INTEGRATION_SETTINGS with $modSettings and then read how earlier in the reloadSettings() function how is creates $modSetting from the smf_settings table and thought about adding a new field 'integrate_pre_include. Thanks for confirming this method. :) This should be good enough to get me starting. I appreciate the fast response.
You might wish consider a small note update to the guide for this subtle missing point for new guys working with SMF. :)
PS: Great software!
Hi Orstio,
Ok, I got the basic coding requirements to synchromized SMF login, logout and register with our backend server.
Give me give the coding pointers for the reverse direction?
Explanation:
Our backend is a 100% intranet - Private by default, authentication required to do anything with the exception of a '/public/' alias, if used, it doesn't force authentication. The /public alias puts a folder on the backend where they can stick any public files, including applications, like PHP. So in this case, the operator installed smf under the server side \doc_root\pub\smf folder thus allowing him to use SMF independent from our authentication system, with the url "/public/smf"
However, if smf is installed under \doc_root\smf, then the url, /smf, will force an authentication before that page will be served.
So basically, whats the recommended way to wrap the smf login, logout, register so that our server code can transparently automate the three basic processes in SMF?
I guess this required setting the $php_session variables, adding a session record to the sql table, etc?
hmmmm? just basically call login2(), logout(), registerMember() with the properly prepared parameters?
thanks
Calling login2 or logout from external will result in a session verification error.
Since SMF relies on cookies to determine login status rather than sessions, you are better off using the cookie directly for login and logout.
If you download the Mambo bridge from the downloads page, you'll see in the files SMF_Login, SMF_Logout and SMF_Register how I handled passing these three items to SMF from an external system. The files are fairly small and straightforward if you can read PHP.
Yes, I downloaded the provided examples to see how the various logics. I'm going to put the this 2nd WINSERVER to SMF authentication to the side for now to get the initial project SMF to WINSERVER auth synchronization done per customer request.
Question:
When the integration is stable (meaning the two databases are in sync), the smf register logic will begin the process. I have to confirm this, yes, I just did a quick register testuser, the plain text password is passed to the integrate_register() function within the $regOptions array passed.
I plan to use the basic three $regOptions[] parameters:
$regOptions['username']
$regOptions['email']
$regOptions['password'] plain text password
$regOptions['register_vars']['passwd'] hashed password
to register the new account at at backend.
This will work, but the sychronization "might" be off for "errors". I noticed that registerMember() calls integrate_register() but it has no result logic flow.
In other words, if the registration fails at the backend, it continues.
I guess I can modified the registerMember() function to provide a functional true, false result when it calls integrate_register(); false means do not continue with SMF database registration.
But would there be another way?
I guess, the better way to discribe this is a need for:
bool integrate_validate_reqister(string $username)
which is called at the top of registerMember to verify that the backend user name is not already taken. It would work similar to integrate_validate_login() function which your notes indicate allows for a failed break out.
I hope this made sense.
Thanks
Yes, I see your dilemma.
Is it PHP 5.x? You could always throw an exception to kick out of the workflow and produce an error message.
Orstio,
QuoteIf you download the Mambo bridge from the downloads page, you'll see in the files SMF_Login, SMF_Logout and SMF_Register how I handled passing these three items to SMF from an external system. The files are fairly small and straightforward if you can read PHP.
Ok, I looked at it. Excellent logic to work with. But it still has the problem, unless there is something I missed where if the remote registration fails, there is no captured logic to abort or revert the SMF registration.
I had this same issue with InstantForums where the databases are now out of sync. No new account recorded on the backend. This was one of the two instances where I had to modified the source code to do a "pre-registration check" before continuing the the logic.
Am I missing something in SMF or something already available to provide this? remember the goal is to work with the your hook system - no modifying to stock code if all possible.
In the mean this, this is what I did to subs-members.php:
// Call an optional function to validate the users' input.
if (isset($modSettings['integrate_register']) && function_exists($modSettings['integrate_register']))
{
//-----------------------------------
// WCSMF Registration Check, 6.3.453.4
//$modSettings['integrate_register']($regOptions, $theme_vars);
if (!call_user_func($modSettings['integrate_register'],$regOptions, $theme_vars))
{
fatal_error(sprintf("Wildcat! User Name not valid: %s",
htmlspecialchars($regOptions['username'])), false);
}
//-----------------------------------
}
I'm assuming fatal_errors aborts/redirections to some graceful error display. I having tried it yet. :)
I see your last message, Nice the SMF smartly detected a new post was available. :)
We only support PHP 5.2.5 to 5.3.0 right now, more specifically, our extension is only compiled for this versions currently.
So you think if my wrapper throws an exception it will suffice here?
If not, can I suggest this change (make it a bool function) or whatever you think is best wish item for before 2.0 goes gold? :)
THX
I haven't been on the SMF team for almost two years. You're asking the wrong guy to make changes. :P
What do you see as a potential for the username to fail in your system but not in SMF?
ETA -- I'd be wary of doing this with any version of 2.0 at this time.
http://www.simplemachines.org/community/index.php?topic=374107.0
Not all the integration hooks are functional in RC3. For integration, stick with 1.1.x until there's some progress.
QuoteI haven't been on the SMF team for almost two years. You're asking the wrong guy to make changes. :P
Oops, sorry. Didn't mean that. :)
Your suggestion to just throw the exception worked perfectly:
function wcsmf_register($regOptions, $themeVars)
{
// initialize context, if not already done
require_once("wildcat.php");
if (!WcInitialize()) {
fatal_error(sprintf("Wildcat! Server Not found: Error %08X",
wcGetLastError()), false);
}
// check if registration name already exist
$uname = $regOptions['username'];
$ui = array();
if (wcLookupName($uname,&$ui)) {
fatal_error(sprintf("Wildcat! User Name Already Exist, try another: %s",
htmlspecialchars($uname)), false);
return false;
}
return true;
}
So we don't need to modify stock code! Wonderful! :)
QuoteWhat do you see as a potential for the username to fail in your system but not in SMF?
Well, from experience in other 3rd party integration, like with InstantForum, when the synchronization is worked out, to install it (SMF), I will need to provide a small utility to
- scan the backend user database to add set a new hashpwd field to hold and set the SMF hash for the user password based on the user's current password, and
- create the SMF user database from the existing backend database.
They would be in sync now for login and logout.
But with a new user SMF registration, it needs to make sure that the backend user account name doesn't exist already before it creates one in SMF. Otherwise, if not checked, the user would be able to login in SMF but the the backend. :)
The main reason it has to be in sync, is there are all sorts of monitoring tools, i.e. help desk, GUI, finger, text mode, etc that can be done from remote. They need to see who's logged in, what they are doing (actiivity colum: SMF Forum - XYZ). I am going to have to also provide hooks for actions such as:
- integrate_disconnect_user()
and other actions but not as important as the disconect which would log off the user at the back end and some how I need to see how to easily hooked in logic where a SMF PHP request will check if the user has been forced off and then force SMF to redirect to some logoff page perhaps. The disconnect can be a manual operator request, system maintenance request and/or session time out. They don't probably have to be 100% here once logged in, but the user can never be logged into SMF without being logged into the backend.
The only reason this has become desirable is because message system is 25 years old and currently lacks the "topical style" of mail displays and authentication is required to even read mail. So we been losing a crowd of people to these new forum (i call them topical views) systems, but more and more are asking for the integration. I wish to satisfy that request and even since we did the PHP extension that ties in our server API, we been getting more PHP applications installed. SMF fits right in and its must say its pretty spiffy. :)
I think people will be very excisted about it. What worries me is that they will also want more to tie in the mail forums, conferences and security access profiles configrations as well and then I am going to figure out what that all means in terms of source code customization, licensing and all that. So for now, starting with synchronizing the session management will suffice for independent operator SMF installation. No changes to stock files. Just provide the minimum extra hooking files.
Thanks for your wonderful assistance. :)
--
Hi Orsito,
You seem to be very much the man in the know for this sort of thing, and I thank you wholeheartedly for the extensive documentation and support provided that has, up until this point, prevented me from needing to pick your brains for the answers to my problems.
Currently, I am attempting to bridge SMF with the PHPMotion CMS on a completely fresh site, with PHPMotion serving as the main directory and SMF in a subdirectory 'forum'. I am using an include on the SMF index page named 'integrate.php' to begin the integration hooks. Currently, I have integrate_verify_user serving to log in and register users on SMF when they log in on to the CMS working well. I have begun working on the logout script using integrate_logout to unset the cookies used by the CMS, however no matter what I have tried, once the script executes and the page reloads, I am always still logged in on SMF & the CMS and the cookies are still present.
My integrate login function
function integrateLogout() {
if ( isset($_COOKIE[user]) && isset($_COOKIE[pass]) ){
$theUsername = $_COOKIE[user];
setcookie('user', '', time() - 3600*25);
setcookie('pass', '', time() - 3600*25);
session_destroy();
mysql_select_db('complete_smf1');
$theIDQuery = mysql_query("SELECT ID_MEMBER FROM smf_members WHERE memberName = '" . $theUsername . "'");
$theUserID = mysql_fetch_row($theIDQuery);
$theUserID = $theUserID[0];
mysql_select_db('complete_cms');
$sql = "DELETE FROM online WHERE logged_in_id = $theUserID";
mysql_query($sql);
mysql_select_db('complete_smf1');
}
}
The logout routine used by the CMS is quite similar, I have tried copying it pretty much exactly for my own function, but still have exactly the same problem:
PHPMotion logout routine
$user_id = "";
$user_name = "";
$random_code = "";
@session_start();
@session_destroy();
setcookie('user', '', time() - 3600);
setcookie('pass', '', time() - 3600);
$sql = "DELETE FROM online WHERE logged_in_id = $user_id";
@mysql_query($sql);
@mysql_close();
//just to be extra sure - set sessions to NULL
$_SESSION['random_code'] = NULL;
$_SESSION['user_id'] = NULL;
$_SESSION['user_name'] = NULL;
$_SESSION["admin_logged"] = NULL;
header("Location: " . "index.php");
I Really don't know why this is happening, my only thought was that perhaps the integrate_validate_login function was executing when index.php refreshes on one of the session cookies and automatically logs in, although I have tried destroying the session data when I was using this code and had no luck..
Can I see the integrate_verify_user function code?
I nabbed it and adapted it slightly from another post on this thread... can't find the original right at this second.
verifyUser function:
function verfiyUser() {
//Is a user logged into CompletelyDark by Cookie?
if (!isset($_COOKIE['user'])) {
return;
} else {
$CDUsername = $_COOKIE['user'];
};
//Check if user is an SMF member
$getSmfUser = mysql_query("SELECT ID_MEMBER FROM smf_members WHERE memberName = '" . $CDUsername . "'");
if (mysql_num_rows($getSmfUser) >= 1) {
$smfUserRow = mysql_fetch_array($getSmfUser);
$smfUserID = $smfUserRow['ID_MEMBER'];
} else { //If not, add CompletelyDark user to SMF member list
//Get user's CompletelyDark account info
mysql_select_db('complete_cms');
$getCDUser = mysql_query("SELECT * FROM member_profile WHERE user_name = '" . $CDUsername . "'");
if (mysql_num_rows($getCDUser) <= 0) {
return;
};
$row = mysql_fetch_array($getCDUser);
//Migrate user to SMF
$smfUserID = migrateToSMF($row['user_name'], $row['password'], $row['email_address']);
};
return $smfUserID;
};
function migrateToSMF($user_name, $password, $email_address){
$join_date = time();
mysql_select_db('complete_smf1');
mysql_query("
INSERT INTO smf_members
(memberName,
realName,
passwd,
emailAddress,
dateRegistered,
ID_POST_GROUP,
lngfile,
buddy_list,
pm_ignore_list,
messageLabels,
personalText,
websiteTitle,
websiteUrl,
location,
ICQ,
MSN,
signature,
avatar,
usertitle,
memberIP,
memberIP2,
secretQuestion,
additionalGroups)
VALUES
('$user_name',
'$user_name',
'$password',
'$email_address',
$join_date,
'4',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'')"
);
$memberID = mysql_insert_id();
mysql_query("UPDATE smf_log_activity SET registers = registers + 1 WHERE date ='" . date("Y-m-d") . "' LIMIT 1");
return $memberID;
}
Cheers for the quick support
I'm going to assume you've been testing this with your admin account, and the ID_MEMBER of that admin account = 1?
Try this:
function verfiyUser() {
//Is a user logged into CompletelyDark by Cookie?
if (!isset($_COOKIE['user']) || $_COOKIE['user']=='') {
return false;
} else {
$CDUsername = $_COOKIE['user'];
}
//Check if user is an SMF member
$getSmfUser = mysql_query("SELECT ID_MEMBER FROM smf_members WHERE memberName = '" . $CDUsername . "'");
if (mysql_num_rows($getSmfUser) >= 1) {
$smfUserRow = mysql_fetch_array($getSmfUser);
$smfUserID = $smfUserRow['ID_MEMBER'];
} else {
//If not, add CompletelyDark user to SMF member list
//Get user's CompletelyDark account info
mysql_select_db('complete_cms');
$getCDUser = mysql_query("SELECT * FROM member_profile WHERE user_name = '" . $CDUsername . "'");
if (mysql_num_rows($getCDUser) <= 0) {
mysql_select_db('complete_smf1');
return false;
}
$row = mysql_fetch_array($getCDUser);
//Migrate user to SMF
$smfUserID = migrateToSMF($row['user_name'], $row['password'], $row['email_address']);
}
mysql_select_db('complete_smf1');
return $smfUserID;
}
I have been testing with an account that I created using the verifyUser function with an ID of 3. I have checked and the user ID is the same on the CMS and SMF db's.
If it would help, I could give you the username and pass so you could log in and see the function executing?
Do the code changes I suggested above make any difference?
Sorry, forgot to mention that... No, it still won't log out unfortunately.
With the integrateLogout function I was able to echo the username and ID, so they are being passed through fine, it just does not seem to be getting rid of the cookie for some reason.
I was also having a little difficulty in accessing the variables that are actually passed to the hook functions, for example in the integrate_delete_member, I need the ID_MEMBER variable, but have no idea how to call it at the moment?
What version of SMF is this?
1.1.11 installed with fantastico.
Well, the ID_MEMBER should be passed to the function. Can I see your code for it?
integrateDeleteMember Function
function integrateDeleteMember($user_id) {
mysql_select_db('complete_cms');
// member profile
$sql = "DELETE FROM member_profile WHERE user_id = $user_id";
@mysql_query($sql);
//videos
$sql = "UPDATE videos SET approved ='pendingdelete' WHERE user_id = $user_id";
@mysql_query($sql);
}
there is more, but they are all SQL delete statements in the same format for the various tables of the database.
I still have had no luck with the logout function. It just seems like a relatively simple bit of code to cause such a headache heh...
In all your functions, when it's done, you need to select the database back to the SMF database before return.
And in stuff like this:
if ( isset($_COOKIE[user]) && isset($_COOKIE[pass]) ){
I'd make sure there are quotes.
if ( isset($_COOKIE['user']) && isset($_COOKIE['pass']) ){
Simple things can sometimes cause major headaches.
Heh, woke up and approached it with a fresh head this afternoon.
Turns out my problem was that I was not setting the cookie paths. I thought that they defaulted to the same value anyway, but making the change from this:
setcookie('user', '', time() - 3600*25);
to this:
setcookie('user', '', time() - 3600*25,'/');
Made all the difference.
I also had to delete my PHPSESSID cookie with another setcookie command. I hope this can help someone who is stuck.
The PHPMotion integration seems to be going well. So far, the registrations, login, logout, reset pass and delete member hooks seem to be running nicely, and I am currently working on integrate_change_member_data.
Which brings me to my next question...
I can't for the life of me think of a method to iterate through each user name, co-ordinating the given variables and data to the relevent fields on the CMS db, given that at any point the $vars and $data could be in a different arrangement depending on what has been supplied to the hook and that the CMS member DB has different field names...
So far I am looping through each name:
foreach($memberNames as $theMember){
Changing the details here would be easy if every time the same $vars are given, but from my experience this hook only seems to return those that have been edited?
You would do best to set up an association array, and change the associated variable in PHPMotion.
$synch_fields = array(
'memberName' => 'username',
'realName' => 'name',
'emailAddress' => 'email',
'ID_GROUP' => '',
'gender'=>'',
'birthdate'=>'',
'websiteTitle'=>'',
'websiteUrl'=>'',
'location'=>'',
'hideEmail'=>'',
'timeFormat'=>'',
'timeOffset'=>'',
'avatar'=>'',
'lngfile'=>'',
);
$field_to_change = $synch_fields[$var];
The hook passes only one $var at a time, so even if there are multiple members getting edited at once, the hook contains only a single field. The only instance in which I can see multiple members getting edited at once is in the group edits in the admin panel, actually.
For some reason, the integrate_change_member_data hook only seems to be passing me the gender result set? I really don't know why as I have tried simply printing the output, and all that ever returns is gender 0?
I am pretty sure that once I can figure out why it is doing this, I may have a working function
function integrateChangeMemberData($memberNames,$var,$data){
mysql_select_db('complete_cms');
$synch_fields = array(
'memberName' => 'user_name',
'realName' => 'first_name',
'emailAddress' => 'email_address',
'ID_GROUP' => '',
'gender'=>'gender',
'birthdate'=>'birthday',
'websiteTitle'=>'',
'websiteUrl'=>'personal_website',
'location'=>'current_country',
'hideEmail'=>'',
'timeFormat'=>'',
'timeOffset'=>'',
'avatar'=>'',
'lngfile'=>'',
'personalText' => 'about_me',
);
for($x=0;$x<count($memberNames);$x++){
for($y=0;$y<count($memberNames);$y++){
for($z=0;$z<count($var);$z++){
$query = mysql_query("UPDATE FROM member_profile SET '$synch_fields[$var]' = $data WHERE user_name = '$memberNames[$y]'") or die(mysql_error());
}
}
}
mysql_select_db('complete_smf1');
}
Wow, you have way too many for loops there.
$var is a single variable, so no need to loop it.
$field_to_change = $synch_fields[$var];
foreach ($memberNames as $memberName){
$query = mysql_query("UPDATE member_profile SET `".$field_to_change."` = '{$data}' WHERE user_name = '{$memberName}'") or die(mysql_error());
}
Thanks so much for your time and patience Orstio, without it this project would have been a lot more difficult..
I have pretty much finished the integration now, just a couple of little hangups on things that I can't work out still.
integrate_change_member_data
function integrateChangeMemberData($memberNames,$var,$data){
$synch_fields = array(
'memberName' => 'user_name',
'realName' => 'first_name',
'emailAddress' => 'email_address',
'ID_GROUP' => '',
'gender'=>'gender',
'birthdate'=>'birthday',
'websiteTitle'=>'',
'websiteUrl'=>'personal_website',
'location'=>'current_country',
'hideEmail'=>'',
'timeFormat'=>'',
'timeOffset'=>'',
'avatar'=>'',
'lngfile'=>'',
'personalText' => 'about_me',
);
$field_to_change = $synch_fields[$var];
mysql_select_db('complete_cms');
foreach ($memberNames as $memberName){
$query = mysql_query("UPDATE member_profile SET `".$field_to_change."` = '{$data}' WHERE user_name = '{$memberName}'") or die(mysql_error());
}
mysql_select_db('complete_smf1');
}
For some reason, every time this gets stuck on the birthday and returns:
for the right syntax to use near '0001-01-01'' WHERE user_name = 'testmotion'' at line 1
Looking at the message, each variable has a single quote' first followed by a double", which could be causing the problem... I have tried various combinations of quotes etc and have had no luck what so ever. Even when I leave the function out of the hook, it still gets caught. Both fields are set as DATE as well on the database, so they should at least be compatible....
Also, my integrate_personal_message function has a problem:
function integratePersonalMessage ($recipients,$from,$subject,$message){
foreach ($recipients as $recipient){
$recipientSMFID = $recipient[0];
mysql_select_db('complete_smf1');
$recipientQuery = mysql_query("SELECT memberName FROM smf_members WHERE ID_MEMBER = '$recipientSMFID'");
$recipientResult = mysql_fetch_array($recipientQuery);
$recipientName = $recipientResult[0];
mysql_select_db('complete_cms');
$IDquery = mysql_query("SELECT user_id FROM member_profile WHERE user_name = '$recipientName'");
$cmsRecipientResult = mysql_fetch_array($IDquery);
$recipientID = $cmsRecipientResult[0];
$senderIDQuery = mysql_query("SELECT user_id FROM member_profile WHERE user_name = '$from'");
$cmsSenderID = mysql_fetch_array($senderIDQuery);
$senderID = $cmsSenderID[0];
$sql = "INSERT into messages (from_username, subject, message, todays_date, to_id) VALUES ('$from', '$subject', '$message', NOW(), '$recipientID')";
mysql_query($sql);
// record a copy in sent items box
$sql = "INSERT into messages_sent (to_username, subject, message, todays_date, from_id) VALUES ('$recipientName', '$subject', '$message', NOW(), '$senderID')";
mysql_query($sql);
}
mysql_select_db('complete_smf1');
}
it copies the message over to both databases successfully, but then dies with an error "8: Undefined offset: 0" which I believe is referring to the $recipient array. I think the problem is that for some reason it is trying to loop past the amount of recipients for the message.
With these last two problems ironed out, the basic integration will be finished. As soon as I have been marked (I am working on this as part of a uni project), I will post this back on here in the hopes that it will be useful to someone on here.
Try this one instead?
$query = mysql_query("UPDATE member_profile SET `".$field_to_change."` = {$data} WHERE user_name = {$memberName}") or die(mysql_error());
Sometimes fields are passed from SMF already with single quotes in the string.
As for your integratePersonalMessage, $recipient is not an array. You have taken the $recipients array, and made it foreach($recipients as $recipient), so each $recipient is a single variable, not an array of values.
With your last solution, it now outputs:
Unknown column 'testmotion' in 'where clause'Which seems to solve the quotes problem, although now it does not recognise the user_name (definitely correct) where it needs to be changed? I tried removing the braces, which out puts the same, and got a couple of blanks when I experimented with other quotes.
Also, are you sure that $recipient is not an array? because $recipients seems to be a multidimensional array ([to][bcc]) and when I try to echo it it comes up with ArrayArray, but when I echo $recipient[0], it returns the ID. Also, when I removed the
- , the script sends the message twice, but with no recipientID
Alright, what if you try this?
$query = mysql_query("UPDATE member_profile SET `".$field_to_change."` = '".$data."' WHERE user_name = '".$memberName."'") or die(mysql_error());
Think I may have already tried that combo...
returns:
for the right syntax to use near '0001-01-01'' WHERE user_name = 'testmotion''
same problem with the mis-matched quotation marks as before.
Bloody Hell...
Took a break to work on some other aspects of the site, created a redirect to search the two systems with one form and am creating the layout now. In terms of the integration, however, the integrate_change_member data is the only one that still does not work.
Its doing my head in, I think I have used every combination of quotes that I can think of, but still no joy...
The best solution seemed to be:
$query = mysql_query("UPDATE member_profile SET `".$field_to_change."` = {$data} WHERE user_name = {$memberName}") or die(mysql_error());
However, this would then not recognise the $memberName variable and returned:
Unknown column 'testmotion($memberName)' in 'where clause'
Where 'testmotion' is very much present in the db system....
I think the problem is with something aside from the query, since at the moment, my integrate_reset_pass function is doing something similar, and it was working fine eariler. It seems to be displaying the same sort of error message, even though it is updating the CMS side (i assume it fails before it updates the SMF password) Plus when I have copied and pasted the query into phpMyAdmin it works fine???
Have you tried this instead?
$query = "UPDATE member_profile SET `".$field_to_change."` = {$data} WHERE user_name = {$memberName}";
echo $query;
exit();
What you need to understand about the error is that it is looking for a table column named "testmotion", not a data entry in the user_name column with a value of "testmotion".
yes, I've read the f. manual http://www.simplemachines.org/community/index.php?topic=173483.0 and http://www.simplemachines.org/community/index.php?topic=371860.0 :)
Please excuse me for that question, I didn't really understood the workflow of integration by hooks.
Assuming that my existing cms is in /www/ and SMF installed in /www/smforum/ on the same machine.
The goal is it no registered user could make an valid login directly to SMF but after login in the existing CMS he/she could seamlessly use the SMF. Theres no need to run it in a frameset, it will open a new browserpage with the default SMF Layout.
So here's what I suggest after reading the whole discussion:
If I want to integrate the SMForum without a second login, I have to provide a link that points to "smforum/index.php", which is calling the several functional-php files in /smforum/sources/.
Now some using of the hooks is possible.
I want a login, so I need the login hooks to tell SMF's Auth-System the necessary values.
- The confusing part is : ------------------------------------
Where I have to place the file with the defined integrate_functions or where I have to reference it?
And which filename it must have? Can I use any_desired.php?
-----------------------------------------------------------------
After providing SMF with all needed login values, it will look if the user is valid and on success it displays a fresh browserwindow with the default forum discussion.
So far.
Could anyone of you wise guys help me please with this very basic skilled problem?
Thank you in advance and thank you for the whole work you've done to build this fine software.
Greets from Germany
(and please excuse my horrible english...)
EDIT: I'm using SMF 1.1.11 and a System similar to but not a known CMS
I believe in the statement, that there's no need to touch any of the SMF Code and there's only one Layer I have to write and put it between SMF and the single Link in my System, that points to SMF.
Sorry for the missing informations.
it seems, the topic
http://www.simplemachines.org/community/index.php?topic=233362.0
will solve the problem.
I have to try it ...
Maybe this will help some other to find the solution much easier than me (4 Days searching and reading a foreign language)
Thank you very much Simon_K for picking out one solution from the thousands of possibilities to realize such a bridge and to publish it.
with best regards
Hello,
as I have to integrate mrbs (http://mrbs.sourceforge.net/) within smf2 I need some help. The goal is a kind of simple integration. That is to give the auth stuff to smf and let mrbs read out
1.) if a user is logged in to smf
2.) what (prime) id_group he has
The memberstructure of mrbs is quite simple: level 0 = readers, 1 = bookers, 2 = admin.
So I greenly think the (mrbs) script has to extract the user and the group compare the rights (ie. groupid9 = 0, ...).
Can this be donne? Any help appreciated.