News:

SMF 2.1.4 has been released! Take it for a spin! Read more.

Main Menu

Multidomain SMF forum

Started by Pedja, May 15, 2007, 11:34:41 AM

Previous topic - Next topic

Pedja

I needed modification of a forum to allow me to run several separate forums on top of the one instalation of SMF forum, with regeuest that whole database should be shared too.

The whole idea was that I can run several virtual forums under different domains but also run one general forum that offers contents fo all virtual forums and some more.

I've done some modifications that do what I needed so here it is:


SMF MULTIDOMAIN MOD
Description:

This mod allows you to have several forums on single board instalation. Each forum is located on separate

domain, and all forums share the same databse od messages, users and setings. You can customize look of each

forum and also choose which categories and boards should be visible in each domain.

Features:

- supports unlimited number of forums
- each forum uses separate domain. Domains can be unrelated or subdomains of the same top domain
- each forum can show configurable categories or boards of the main forum. This means you may have lots of

boards on forum but show just one category, or just one board for specific forum.
- each board can be shown or hidden on any forum
- each category can be shown or hidden on any forum
- each forum can use different template, so you can independently customize each forum look
- each forum can use different logo if you do not need to change complete look
- each forum can have different forum name
- each forum can have different HTML description
- each forum can have different HTML keywords
- last unread posts, new replies, search andother forum functions that should be affected by domain filter, are

affected
- mod does not change SMF tables, just adds one independent table for it's configuration
- mod is implemented on SMF 1.1 RC3 but it should be aplicable to any 1.x version


How to do modification:

This may look as lots of work but actualy it is not. It would be easier if this mod is realised aspackagebut I

do not know how to createpackage. If anyone is willing to makepackageof this, that would be great.


- park new domain on top of the primary forum domain. Make sure, that, when you open new domain in browser you

get working forum. note that all links on forum stil point to priamry domain.


- change seetitngs.php to force SMF to use current domain for all links:


open Settings.php

find



$boardurl = '



the rest of the line would be the already set (primary) domain

comment that line (put // as the very first in the line) and add new line below:



$boardurl = 'http://' . $_SERVER['HTTP_HOST'];




Now reload forum on new domain (not primary) and check if all links point to it domain

That is fixed


Create table smf_domain_forums in forum database. Pay antention to table prefix if you do not use default smf_

prefix.



CREATE TABLE `smf_domains` (
`domain_id` smallint(5) unsigned NOT NULL auto_increment,
`domain` varchar(35) NOT NULL default '',
`categories_show` varchar(35) NOT NULL default '',
`categories_hide` varchar(35) NOT NULL default '',
`boards_show` varchar(35) NOT NULL default '',
`boards_hide` varchar(35) NOT NULL default '',
`THEME_ID` tinyint(4) default NULL,
`header_logo_url` varchar(35) default NULL,
`forum_name` varchar(35) character set utf8 default NULL,
`keywords` text character set utf8,
`description` text character set utf8,
`wellcome` text character set utf8,
PRIMARY KEY (`domain_id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;




Insert at least one record in this table. Fields domain, categories_show, categories_hide, boards_show, and

boards_hide must not be NULL.



INSERT INTO smf_domains (domain, categories_show, categories_hide, boards_show, boards_hide, THEME_ID,

header_logo_url, forum_name, keywords, description) VALUES ('','','','','',NULL,NULL,NULL,NULL,NULL);



Domain match is set by filling domain field in record. It may apsolutely match requested domain but any substring match will do. Contents of domain field must be substring of host domain used for forum access. If several records match, the first one is used.

Now edit Sources/Load.php and at the bottom of the php code (just before ?> ) insert



// multidomain support
// load settings for current domain if it is customised for multidomain use
function loadDomain() {
global $db_prefix, $context;

$smf_domain = $_SERVER['HTTP_HOST'];

$query = "SELECT DISTINCT *
FROM

{$db_prefix}domain_forums
WHERE (INSTR('$smf_domain', domain) > 0)";

$request = db_query($query, __FILE__, __LINE__);

$row_domain = mysql_fetch_assoc($request);
mysql_free_result($request);

$context['custom_domain'] = $row_domain;
$m_row_domain = $row_domain['domain'];

$query = "
SELECT b.ID_BOARD, b.ID_CAT
FROM {$db_prefix}boards as b, {$db_prefix}domain_forums as df
WHERE df.domain = '$m_row_domain'
AND ( FIND_IN_SET(b.ID_CAT, df.categories_show) OR FIND_IN_SET(b.ID_BOARD,

df.boards_show) OR ((df.categories_show = '') AND (df.boards_show = '')) )
AND NOT (FIND_IN_SET(b.ID_CAT, df.categories_hide))
AND NOT (FIND_IN_SET(b.ID_BOARD, df.boards_hide))";
$request = db_query($query, __FILE__, __LINE__);

$boards_list = '';
$categories_list = '';

while ($line = mysql_fetch_assoc($request)) {
if (!empty ($boards_list)) $boards_list .= ',';
$boards_list .= $line['ID_BOARD'];
if (!empty ($categories_list)) $categories_list .= ',';
$categories_list .= $line['ID_CAT'];
}

mysql_free_result($request);

$context['custom_domain']['boards_list'] = $boards_list;
$context['custom_domain']['categories_list'] = $categories_list;


} // end loadDomain()


function customDomainConfiguraion() {
global $context, $settings;

//multidomain feature
//set custom domain header logo
if (! empty ($context['custom_domain']['header_logo_url'])) {
$settings['header_logo_url'] = $context['custom_domain']['header_logo_url'];
}
if (! empty ($context['custom_domain']['forum_name'])) {
$context['forum_name'] = $context['custom_domain']['forum_name'];
}
if (! empty ($context['custom_domain']['keywords'])) {
$context['keywords'] = $context['custom_domain']['keywords'];
}
if (! empty ($context['custom_domain']['description'])) {
$context['description'] = $context['custom_domain']['description'];
}

} // customDomainConfiguraion()






Now find function function loadUserSettings() in the same file. Find line



global $ID_MEMBER, $db_prefix, $cookiename, $user_info, $language;



and insert innext line this code



global $context;




Go to the last line of that funcion, and at the very bottom of function definition (just before } ) insert this




// multidomain feature
// set filter to boards to show only those that are attached to custom domain
// if(!isset($_REQUEST['action']) && !isset($_REQUEST['board']) &&!isset($_REQUEST['topic'])){
if(!isset($_REQUEST['board']) &&!isset($_REQUEST['topic'])){
$row_forumList = $context['custom_domain'];

$user_info['query_see_board'] .= ' AND FIND_IN_SET(b.ID_BOARD, "' .

$row_forumList['boards_list'] . '") ';

// $user_info['query_see_board'] .= ' AND (' ;
// $user_info['query_see_board'] .= (int) (empty($row_forumList['categories_show']) and

empty($row_forumList['boards_show'])) ;
// $user_info['query_see_board'] .= ' OR FIND_IN_SET(c.ID_CAT, "' .

$row_forumList['categories_show'] . '")';
// $user_info['query_see_board'] .= '  OR FIND_IN_SET(b.ID_BOARD, "' .

$row_forumList['boards_show'] . '") )';
// $user_info['query_see_board'] .= ' AND NOT (FIND_IN_SET(c.ID_CAT, "' .

$row_forumList['categories_hide'] . '")';
// $user_info['query_see_board'] .= ' OR FIND_IN_SET(b.ID_BOARD, "' .

$row_forumList['boards_hide'] . '"))';

}





Find function loadTheme and search for



// Wireless mode? Load up the wireless stuff.
if (WIRELESS)



and insert before that code



// multidomain feature
// adjust configuration according to custom domain settings
customDomainConfiguration();





Now, find



elseif (!empty($board_info['theme']))
$ID_THEME = $board_info['theme'];
// The theme is the forum's default.
else
$ID_THEME = $modSettings['theme_guests'];




and replace with


elseif (!empty($board_info['theme']))
$ID_THEME = $board_info['theme'];
// The theme is the domain's default.
elseif (! empty ($context['custom_domain']['THEME_ID'])) {
$ID_THEME = $context['custom_domain']['THEME_ID'];
} else
$ID_THEME = $modSettings['theme_guests'];




Open Sources/BoardIndex.php and find




AND b.childLevel <= 1" : ''), __FILE__, __LINE__);



replace it with



AND b.childLevel <= 1" : '') . " ORDER BY c.catOrder, b.boardOrder ASC" , __FILE__, __LINE__);




Open index.php

Find



// Load the user's cookie (or set as guest) and load their settings.
loadUserSettings();


and before that insert



//multidomain feature
//Load custom domain information
loadDomain();




Open Sources/Recent.php

Find function getLastPosts and within the first SQL query search for



WHERE m.ID_MSG >= " . max(0, $modSettings['maxMsgID'] - 20 * $showlatestcount) . "
AND t.ID_TOPIC = m.ID_TOPIC


Replace it with



WHERE t.ID_TOPIC = m.ID_TOPIC




Now you will have pretty functional forum for each domain.




ADDITION


Now, do you want option to change order of categories on additional domain? Let's do some more modifications.

First create new table



CREATE TABLE `smf_domain_categories` (
`domain_id` smallint(5) unsigned NOT NULL default '0',
`ID_CAT` tinyint(4) unsigned NOT NULL default '0',
`catOrder` tinyint(4) unsigned NOT NULL default '0',
`name` tinytext character set utf8,
PRIMARY KEY (`domain_id`,`ID_CAT`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;



Check table smf_domains

It should have this field:

   `domain_id` smallint(5) unsigned NOT NULL auto_increment,

and primary key set to domain_id

   PRIMARY KEY (`domain_id`)

If the structure of the table smf_domains in your databse differs from the one provided on top of this document the best would be to recreate whole table. That would save you trouble of matching and updating differences (unfortunately, this modification is work in progress, so I had to change structure of the table)


Now, open Sources/BoardIndex.php and find




AND b.childLevel <= 1" : ''



Do you find it familiar? Right that's where we already made a change to get categories inorder. Now we have to change that SQL to get more. Go to the begining of SQL query and do this

Find



c.name



and replace it with



IFNULL(dc.name, c.name)



Find



ORDER BY c.catOrder



and replace it with

ORDER BY IFNULL(dc.catOrder, c.catOrder)



Also, after the last LEFT JOIN line in query insert new one

[code]

LEFT JOIN {$db_prefix}domain_categories as dc ON (dc.ID_CAT = c.ID_CAT) AND

(dc.domain_id = " . $context['custom_domain']['domain_id'] . ")



Now, this would work but domain dependant category name would not show everywhere. We have to find every place in code that shows c.name in query and do similar replacements. there is just one imortant place that should be fixed:

Open Load.php

Find c.name. It should occur two times. The First time it is ni function loadBoard().

Replace



c.name



and replace it with



IFNULL(dc.name, c.name)



and after the last LEFT JOIN line in the same SQL query insert new one



LEFT JOIN {$db_prefix}domain_categories as dc ON (dc.ID_CAT = c.ID_CAT) AND

(dc.domain_id = " . $context['custom_domain']['domain_id'] . ")




The second occurence fo the c.name is in function loadJumpTo(). You may do the same alteratin of the query here. That would fix name od category in Jump To compo box. I have this combo disabled so I did not care.


Now you have to populate table. Notice that now, each record in smf_domains has doman_id which must be unique

number. This number is used as referncein smf_domain_categories. When you want to set order of categories,

remembre domain_id from smf_domains for targeted domain and put it in domain_id in smf_domain_categories for

each category (ID_CAT) you want to set.

You may now set catOrder (order of the category) and name (name of the category that would be presented on

forum). Scripts works in that way that if tries to use category order and naem form smf_domain_categories table,

and if there is no setting the it would use setting from the main domain.




Note: This code has been updated.

You must notice that table name is changed form smf_domain_boards to smf_domains to match general table naming standards.

Also, structure of the table is changed a bit. Autoincrement field 'domain_id' is added, and PK changed to use this new field. Also, some character fields are set to UTF8 encoding.

Adition to this code is added do provide option to change order of categories and categories names based on used doman.

Attention:

Althrough modification are not large and are quite simple and straightforward, please do not try to do this if you do not have some experience with PHP. Be sure to make backup of all scripts you are going try to change.

Note that in this modification I assumed you use default SMF table prefix. If you use different prefix, you should change table creation scripts accordingly.
[/code]

KGIII

Nice post. Let me call attention to the rest of the team.

My PC Support Forum
Please ask in-thread before PMing
                   SMF Help
                   Visit My Blog

How can we improve the support process?:
http://www.simplemachines.org/community/index.php?topic=163533.0

SMF vs. Godzilla? Who do you think will win?

KGIII

Move to tips and tricks. Enjoy.

My PC Support Forum
Please ask in-thread before PMing
                   SMF Help
                   Visit My Blog

How can we improve the support process?:
http://www.simplemachines.org/community/index.php?topic=163533.0

SMF vs. Godzilla? Who do you think will win?

Pedja

#3
No, this does the oposite: you install one SMF forum and then assign several domains to it and set which forums and categories may be seen on which domain. You may also set template and few other options for each domain.

At the end you have one SMF, one database, and unlimited number of forums that share the same user and message base but show just what they need.

Thug life

Quote from: Pedja on May 17, 2007, 05:41:09 PM
No, this does the oposite: you instal one SMF forum and then assign several domains to it and set which forums and categories may be seen on which domain. YOu can slo set template and few other options for each domain.

At the end you have one SMF, one database, and unlimited number of forums that share the same user and message base but show just what they need.


Ahhh i think this is what this guy did, they are both the same forum but seperated between 2 domains

www.moparisthebest.com/smf www.moparscape.org/smf [nofollow]

Been like that for a while now, never noticed it

mrperson13

I did all this and then it came up with an error on line 149 of index.php.  That happens to be where loadDomain(); is.  Any idea what's wrong on my board?  I'm glad I backed everything up and fell back on the backup version because it didn't work.

I'm also not too great with php, and a lot of these steps assumed you know a lot about php.  In phpmyadmin I managed to complete all the steps sucessfuly (i think) but it was still a no go.



Also, look at what is said here.  It doesn't tell you what to open (about half way down the post)

Quote from: Pedja on May 15, 2007, 11:34:41 AM
Open Sources/BoardIndex.php and find




         AND b.childLevel <= 1" : ''), __FILE__, __LINE__);



replace it with



         AND b.childLevel <= 1" : '') . " ORDER BY c.catOrder, b.boardOrder ASC" , __FILE__, __LINE__);





Find



elseif (!empty($board_info['theme']))
$ID_THEME = $board_info['theme'];
// The theme is the forum's default.
else
$ID_THEME = $modSettings['theme_guests'];




and replace with


elseif (!empty($board_info['theme']))
$ID_THEME = $board_info['theme'];
// The theme is the domain's default.
elseif (! empty ($context['custom_domain']['THEME_ID'])) {
$ID_THEME = $context['custom_domain']['THEME_ID'];
} else
$ID_THEME = $modSettings['theme_guests'];
       




I found it, but I'm at work now and I forgot what file it was in.  It wasn't in boardIndex.php though.

I would really like to do this to my forum, but like I said I had problems with that line.  If someone could maybe re-write this and make it 'sound' a bit more simple that would be awesome.

mrperson13

By the way, as I stated before I'm kinda of new to php.   What I did was make a notepad file with this in it:

CREATE TABLE `osmf_domain_forums` (
  `domain` varchar(35) NOT NULL default '',
  `categories_show` varchar(35) NOT NULL default '',
  `categories_hide` varchar(35) NOT NULL default '',
  `boards_show` varchar(35) NOT NULL default '',
  `boards_hide` varchar(35) NOT NULL default '',
  `THEME_ID` tinyint(4) default NULL,
  `header_logo_url` varchar(35) default NULL,
  `forum_name` varchar(35) default NULL,
  `keywords` text,
  `description` text,
  PRIMARY KEY  (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO osmf_domain_forums (domain, categories_show, categories_hide, boards_show, boards_hide, THEME_ID, header_logo_url, forum_name, keywords, description) VALUES ('','','','','',NULL,NULL,NULL,NULL,NULL);


And renamed it to .sql then imported it to my database via phpmyadmin.  Was that right?

Pedja

Quotemrperson13
I did all this and then it came up with an error on line 149 of index.php.  That happens to be where loadDomain(); is.  Any idea what's wrong on my board?  I'm glad I backed everything up and fell back on the backup version because it didn't work.

Wnat exact error showed up?

Indeed you have to make backup on each file before you start altrations.

Quote

I found it, but I'm at work now and I forgot what file it was in.  It wasn't in boardIndex.php though.


Quote
Find



elseif (!empty($board_info['theme']))
$ID_THEME = $board_info['theme'];
// The theme is the forum's default.
else
$ID_THEME = $modSettings['theme_guests'];




and replace with


elseif (!empty($board_info['theme']))
$ID_THEME = $board_info['theme'];
// The theme is the domain's default.
elseif (! empty ($context['custom_domain']['THEME_ID'])) {
$ID_THEME = $context['custom_domain']['THEME_ID'];
} else
$ID_THEME = $modSettings['theme_guests'];
&nbsp; &nbsp; &nbsp; &nbsp;




My mistake. This should be found an replaced in Load.php. I'll fix the first message where mod is explained.

Quote
And renamed it to .sql then imported it to my database via phpmyadmin.  Was that right?

Sure,  that is one way to do it.

Pedja

I've updated modification instructions. There are some changes in previous code. Please not that, from now on, table smf_domain_boards is renamed to smf_domains

Also, I expanded modification with explanation how to change order and names of categories independently for each domain.


mrperson13

The error im getting is :

QuoteParse error: syntax error, unexpected ')' in /home/.funny/mrperson13/shatteredkingdom.org/Sources/Load.php on line 543

That line is:
$user_info['query_see_board'] .= ' AND FIND_IN_SET(b.ID_BOARD, "' .

Also, should all those &nbsp; be in your code?  I took them out and replaced them with the tab key after it didn't work, but that didn't solve the problem either.

Pedja

here is part of the code around that line from my Load.php so check if you made all corrections:

Quote
   // multidomain feature
   // set filter to boards to show only those that are attached to custom domain
//   if(!isset($_REQUEST['action']) && !isset($_REQUEST['board']) &&!isset($_REQUEST['topic'])){
   if(!isset($_REQUEST['board']) &&!isset($_REQUEST['topic'])){
      if (!empty ($context['custom_domain'])) {
         $row_forumList = $context['custom_domain'];
         $user_info['query_see_board'] .= ' AND FIND_IN_SET(b.ID_BOARD, "' . $row_forumList['boards_list'] . '") ';
      } else {
         print '@@@ domain undefined @@@';
      }
   }

Those &nbsp; showed up when I pasted code. I did not notice them. You may just remove them, or replace with tabs, it does not matter.

Pedja

I managed to improve this modification to allow admin to move board to another category on specific separate domain, and also to rename board for specific domain.

i stil have to do some work to solve child . parent relation among boards so it would alow even that to be changed for specific domain: one board could be child of another on one domain, and top level board on another.

mdp

Pedja,
I have to ask you this if your step by step process is necessary when two domains are using one same webserver?

When I had phpbb2, all I had to do is change the setting of username and password then that took care of everything.  Pretty simple!  Your process seems more complex than phpbb2..


Sarge

This mod is similar to one I wrote: Shared Forum Mod. But your mod features multiple domains support, which is nice. ;)

    Please do not PM me with support requests unless I invite you to.

http://www.zeriyt.com/   ~   http://www.galeriashqiptare.net/


Quote
<H> I had zero posts when I started posting

mdp

Pedja,

I am getting error message

"Fatal error: Call to undefined function: loaddomain() in /home/thunder/public_html/index.php on line 147"

Pedja

This error means, there is no loaddomain() function in Load.php

About similarity with phpBB - I guess it could not be easier to make this functionality with PHPBB, except if it already does not support multidomain feature.

If you just need the same forum to be seen under two different domains, that indeed is easy in SMF and I guess phpBB too. but, if you want forum to look differently, display different categories and subforums, change their order etc., then some extensive changes in code are necessary, as you can see mostly in SQL queries.

U guess it would be similar complexity to achieve the same functionality under phpBB. In SMF, it is actually simplified by the way how filtering is originally done.

Actually, all this changes are straightforward when you understand how it works.


Sarge, your mod is similar, you did the good work. But, it lacks some functionality I wanted. First, I wanted multidomain feature (and not support for portal), and then, I managed to find simpler way to make it work and provide more functions.

mdp

Pedja,

Assume I want two separate websites to use one same forum, registered member, and picture gallery but not same TP and theme design then what would you recommend??  This is what I am trying to work on right now and I would appreciate some help..

mdp

and actually there is loadDomain() at Source/load.php page just before the ?> so don't know why it is causing error message on index.php  I followed everything you said except for the "In Addition" part. 

Sarge

Quote from: Pedja on June 05, 2007, 06:07:39 PM
Sarge, your mod is similar, you did the good work. But, it lacks some functionality I wanted. First, I wanted multidomain feature (and not support for portal), and then, I managed to find simpler way to make it work and provide more functions.

Would like to join forces with me? We could make a better mod out of the two. ;)

Regarding my mod, I fully plan to remove any requirement for TP (while providing support for it) and make the code more modular. I have already started on the next major version.

    Please do not PM me with support requests unless I invite you to.

http://www.zeriyt.com/   ~   http://www.galeriashqiptare.net/


Quote
<H> I had zero posts when I started posting

Pedja

Quotemdp

... and actually there is loadDomain() at Source/load.php page ...


Pay attention that function is called loadDomain() and error shows that loaddomain() is missing. Missing function is named all in lower case.

Quotemdp
Assume I want two separate websites to use one same forum, registered member, and picture gallery but not same TP and theme design then what would you recommend??  This is what I am trying to work on right now and I would appreciate some help..

Well, I have no experience with TP, so I cannot tell. Point of my modification that all what is needed to make totaly different forun on top of already installed is to assing separate domain. When you access forum on any of the domains it would behave as totaly independednt and fully functional forum.

This means, you can change looks and contents but message and user base stays the same.

Go ahead and take look:

http://forum.uzice.net
http://oglasi.uzice.net
http://forum.vpts.uzice.net
http://forum.datavoyage.com
http://blog.forum.uzice.net/

That is all the same forum. It just behaves differently depending on domain.

If you can make two TP's to work with forums on separate domains (which I do not see why would not work), you would have no problems.

QuoteSarge

Would like to join forces with me? We could make a better mod out of the two.


Sure, why not?


Advertisement: