I need to modify $user_info[query_see_board]

Started by Furvert, July 29, 2005, 03:59:18 PM

Previous topic - Next topic

Furvert

I need to make a small change in  $user_info[query_see_board] but I dont seem to find where that is computed. Security.php was where I expected to see it but no luck. I am still very much a newbie on PHP and SMF files but I am very good at modifing things and solving problems. Sadly this user_info may be well hidden or a basic feature of something else not actually part of SMF code?

My intent is to add an AGE permission and that check is what would be effected by it. It should not be difficult to add a field for age minimum somewhere in the database and the code to check birthdate for AGE is simple. I guess what I will need to do is add an extra column to board data to hold MinAge, default of 0. And unset birthdays calculate as '0' so they are ok in general but fail when MinAge is set.

Yes I know this is a bit more advanced than my previous mod so I want to be sure I am not interfering with the normal permissions at all.

related posts- http://www.simplemachines.org/community/index.php?topic=43141.0
http://www.simplemachines.org/community/index.php?topic=43130.0

On a related note, if anyone can point me in the right direction for what changes are needed to finish my AGE in Memberlist mod- http://www.simplemachines.org/community/index.php?topic=43130.msg313198#msg313198

I suspect it may work as shown but I dont know how to package it for others.
The mod itself works fine with no errors or problems other than it needs a fix for languages.

Thanks for any help
http://furvert.net/smf/index.php
test/test

edit-I found the function in load.php, so hopefully I can see how to change it.
Since permissions are all 1/0 based it would require major editting to use a board MinAge number. Thus it would appear that a `smf_settings` of 'Adult_Age=18' and adding a  'Adult_Age_Required' check box to board permissions would be easiest. So if I read it correctly the MOD needs to only change 'ModSettings.php', 'ManagePermissions.php' and 'Load.php' to allow editting and use.

edit- No this is very difficult to do. Board permissions are only membergroup based.

Furvert

After looking through Permissions and other systems the only reasonable method appears to be to add a new board property. Thus I am back to use of 'Min_Age' with default of '0'. This should require changes to 'ManageBoards.php' to add the editting capability. Then a change to 'Load.php' so that '$user_info['query_see_board']' will check this new property versus AGE calculation(with no age set=0). There may be other checks needed in 'Load.php' to guarentee security. Likely some templates will need changes to show the new property as well. And with new text comes new $txt[] definitions for the templates. Finally it would need to add the new column to the boards in the database, default '0'.

Overall this doesnt appear to bad as a Mod and would have no adverse impacts to operations with the default. Use of 'Min_Age' allows for more flexibility in restricting board access on a perboard level than the alternate permission method of Adult, so it is far better.

I am still having trouble determining how to construct '$user_info['query_see_board']', Is it an array so that all boards are checked at once or is it checked on a per board level. Per board is simpler to do the Mod for as it only needs a single lookup of that boards 'Min_Age'. Since 'b.' is used I would think it is per board, thus only a small Mod to AND the age restriction is needed.

So would an expert please comment on whether I am on the right track with this Mod? Or did I miss something important? I dont want to try doing a lot of changes and tests if it is doomed to fail.

Thanks for any assistence

Furvert

My first guess, I am unsure about the format used in the commands with ' and . in them.

This code would be the MOD in Load.php to take the user's birthdate (hopefully $user_settings['birth_date'] is correct) and compare to the Board's Min_Age ( Hopefully $board_info['Min_Age'] is correct for that) and set $AGE_OK. Of course Min_Age will have to be added to the boards in the database and likely some code added to make sure it is loaded.

I just need to add AND $AGE_OK to the $user_info['query_see_board'] formulas to make it require that it passes the AGE check. As a result any failure will not show that board. For security, it may be required in other places to prevent bypassing by direct links. Other permissions of course still apply if needed.


if (empty($user_settings['birth_date']))
{
$AGE = 0;
}
else
{
list ($birth_year, $birth_month, $birth_day) = sscanf($user_settings['birth_date'], '%d-%d-%d');
$datearray = getdate(forum_time());
$AGE = empty($birth_year) ? 0 : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day)) ? 0 : 1
);

$AGE_OK = ($AGE >= $board_info['Min_Age']);

// Just build this here, it makes it easier to change/use.
if ($user_info['is_guest'])
$user_info['query_see_board'] = '( FIND_IN_SET(-1, b.memberGroups)' . "AND $AGE_OK ");
// Administrators can see all boards.
elseif ($user_info['is_admin'])
$user_info['query_see_board'] = '1';
// Registered user.... just the groups in $user_info['groups'].
else
$user_info['query_see_board'] = '( (FIND_IN_SET(' . implode(', b.memberGroups) OR FIND_IN_SET(', $user_info['groups']) . ', b.memberGroups))' . "AND $AGE_OK ");


I hope some expert can point out any errors for me.
Thanks for any help in this.

Furvert

#3
With trial and error testing, I have discovered that this location in Load.php is very hard to work with. As a simple test I cant even make this work. Likely every method I have used to get 'birthdate' is undefined at this point. I finally learned a bit more on how to work with $user_info['query_see_board'], it is actually a text string, not a bool like I first thought.

//JH-MinAge mod
if (empty($user_profile[$ID_MEMBER]['birthdate']))
{
$AGE = 0;
}
else
{
list ($birth_year, $birth_month, $birth_day) = sscanf($user_profile[$ID_MEMBER]['birthdate'], '%d-%d-%d');
$datearray = getdate(forum_time());
$AGE = empty($birth_year) ? 0 : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day)) ? 0 : 1);
}

//$AGE_OK = ($AGE >= $board_info['Min_Age']);
$AGE_OK = ($AGE >= 18);//test

// Just build this here, it makes it easier to change/use.
if ($user_info['is_guest'])
$user_info['query_see_board'] = ($AGE_OK) ? 'FIND_IN_SET(-1, b.memberGroups)' : '0';
// Administrators can see all boards.
elseif ($user_info['is_admin'])
$user_info['query_see_board'] = '1';
// Registered user.... just the groups in $user_info['groups'].
else
$user_info['query_see_board'] = ($AGE_OK) ? '(FIND_IN_SET(' . implode(', b.memberGroups) OR FIND_IN_SET(', $user_info['groups']) . ', b.memberGroups))' : '0';
//JH-MinAge mod-end


I found a 'birthdate' that works here, so that is a step forward.

if (empty($user_settings['birthdate']))
{
$AGE = 0;
}
else
{
list ($birth_year, $birth_month, $birth_day) = sscanf($user_settings['birthdate'], '%d-%d-%d');
$datearray = getdate(forum_time());
$AGE = empty($birth_year) ? 0 : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day)) ? 0 : 1);
}

[Unknown]

#4
Sorry for the late response...

The query_see_board is inserted into queries to limit the boards people have access to.

You'll want to add to the string like this:

$user_info['query_see_board'] .= ' AND b.MinAge <= ' . (int) $AGE;

-[Unknown]

Furvert

Thanks, I had hoped you would notice eventually.  Anyway it gave me reasons to learn more while I waited ;D.

I had figured the b.MinAge was going to be required since there is no board reference in Load.php. Passing a command string makes context interesting as the location used has to support everything.

I didnt want to have to run the AGE calculation everywhere, so I was happy to see it can be done just the once.

The string caused me a lot of confusion, until I figured out it was a string and not some odd formated bool calculation. Knowing SQL would help too LOL. All the code I have been making were based on code around it. I am litterally formating based on what exists since I dont know for sure what is the correct language, it looks like a C derivitive. I need to find some reference files somewhere.

Well, this mostly finished the actual working section, now the user interface and change to the board database is needed. I need to add MinAge to the board and verify it is read by the queries correctly. Sadly I still dont have direct database edit capability so I will have to write an installer file to make the change. I should be able to look into the exported SQL from my forum to find what table needs the add.

Thanks again for the help
I need to get this working soon as I am going to add SMF login to my gallery site so I will have thousands loging in after that and manual setting membergroups based on age would take alot of time. Warner Bros required me to restrict certain sections and SMF can do this nicely.

[Unknown]

Quote from: Furvert on August 02, 2005, 01:52:06 PM
The string caused me a lot of confusion, until I figured out it was a string and not some odd formated bool calculation. Knowing SQL would help too LOL. All the code I have been making were based on code around it. I am litterally formating based on what exists since I dont know for sure what is the correct language, it looks like a C derivitive. I need to find some reference files somewhere.

PHP is widely acknowledged to be one of the best documented languages around.  This is part of why it is used for the template system.

http://www.php.net/manual

MySQL is fairly well documented too:

http://dev.mysql.com/doc/mysql/en/

-[Unknown]

Furvert

Thanks for the refs
Interesting PHP implies " would use $vars so that these two lines are the same

$user_info['query_see_board'] .= ' AND b.Min_Age <= ' . (int) $AGE;
$user_info['query_see_board'] .= " AND b.Min_Age <= $AGE";


[Unknown]

True, except the following:
  - casting $AGE to an int (which is really a conversion not a cast) ensures no injection hole for safety's sake.
  - using double quotes and interpolation is - arguably - slower than using concatenation and double quotes.

-[Unknown]

wgm

#9
This may come in handy, I have one forum that is adult oriented, and if the member adds his or her full birth date, will give them automatic access, if age permits.

Right now its hidden till 100+ posts.

Furvert

Thanks [Unknown], the advantage of experience ;D
I think this is the correct database command needed to add the MinAge to boards.
I should just need to put it in a php file with the correct wrappers and run it. Then I can work on the next part of the mod, the user interface, always the worst part.
Do you think the existant database queries will load the values ok or will they need mods? So much is done generically that its possible they work ok.

db_query("REPLACE INTO `{$db_prefix}smf_boards`` (`variable`, `value`) VALUES ('MinAge', '0');", __FILE__, __LINE__);

Thanks for all the help, I am slowly getting better at this.

Hi wgm, did you hand code the restriction?
I think Ben_S wrote some code that works ok for single boards. http://www.simplemachines.org/community/index.php?topic=43141.0
I am trying to do the 'improved' method :D
One that will work under admin control and will allow for each board to have different AGE restrictions if needed.

I currently am assuming AGE is ANDed but now I am not so sure that is always best. I may have to allow an override? Well maybe not, anyone who is moding,etc should also have AGE.

[Unknown]

Quote from: Furvert on August 02, 2005, 11:05:37 PM
Do you think the existant database queries will load the values ok or will they need mods? So much is done generically that its possible they work ok.

db_query("REPLACE INTO `{$db_prefix}smf_boards`` (`variable`, `value`) VALUES ('MinAge', '0');", __FILE__, __LINE__);

Actually, that's how you add rows.  In this case, what you suggested is roughly how to add rows to the settings table.

However, you want to add a column.  The settings table only has two columns: variable and value.  To add a column, you use this:

db_query("
   ALTER TABLE {$db_prefix}boards
   ADD COLUMN MinAge tinyint(3) unsigned NOT NULL default 0", __FILE__, __LINE__);


Here, we define the column as follows:
  - name: MinAge.
  - type: tinyint (a number from -127 to 127 or 0 to 255.)
  - unsigned (so, 0 to 255 - ages can't be below zero!)
  - never NULL (because 0 is all we need, and this saves space in the database.)
  - default to 0 - no restriction.

However, this query will fail if it's run a second time on a table that already has this column.  So, in 1.1, you would use:

db_query("
   ALTER TABLE {$db_prefix}boards
   ADD COLUMN MinAge tinyint(3) unsigned NOT NULL default 0", false, false);


To ignore errors.  In 1.0, you have to use:

mysql_query("
   ALTER TABLE {$db_prefix}boards
   ADD COLUMN MinAge tinyint(3) unsigned NOT NULL default 0", $GLOBALS['db_connection']);


Which will also ignore the error, but is... less "correct" as far as SMF's system is concerned.

Adding a column won't break anything, because all of the INSERT queries in SMF qualify column names.  For example, this query:

INSERT INTO smf_settings
VALUES ('x', 'y');

Will fail if a column is ever added to the settings table, and as such is a bad idea.  However, this query:

INSERT INTO smf_settings
   (variable, value)
VALUES ('x', 'y');

Will always work.  SMF has, of course, been designed with mods in mind - modifying table structures is supposed to be easy ;).

-[Unknown]

Furvert

Thanks [Unknown] that was a big oops. Odd I used that from someone elses mod, I guess I didnt look close enough as to what it modified.  :(

I am targeting SMF1.1b3p since that is what I am using and is closer to what you are working with for the future. Most of my mods would not be too hard to make work with older versions but just add to my work load! LOL Maybe later I will check for other versions with a smarter mod method.

I will need to read through the 'ManageBoards.php' and similar places for where to add the edit MinAge, and to the 'ManageBoards.template.php' for that as well. Hopefully it wont need much more than that to make it usable. I really dont want to effect too many places as its too easy to cause major side effects. This mod should have minimal code impacts because it ties into Load so as to be automatically used elsewhere.

brandongco

Just curious... how's the progress on this coming? I could really use something like this on my site!

Furvert

Progress..eeeeeeeeeeeeeeeeeeek!
Actually I managed to make the basic stuff work fine with a few tips from [Unknown]
I have not actually changed my database yet so I have not gotten any further.

The code will function as desired, but it needs the field added to the database and Admin interface added to allow setting and editing the number in manage.boards.php and any associated templates.
This is just an add of one value to those pages so it should not be too difficult to locate a good spot.

Hopefully I will get to that soon, I was distracted by other things IRL

rojamaia


this mod is great! i hope that it would be finished soon.

good luck Furvert!  i'd keep on checking on this from time to time

Ohmer

Hello,

Did you completed and released this mod ?  It would be very usefull for my forums but didn't find any copy to download.

Thanks

Furvert

Sorry I still have not worked on it further
I am still using 1.1b3p and was going to update to newer version then paniced as I did not want to have to rerwrite what I already had on the site. Also there were many who had problems with the mods I have been using and the new versions, so I waited and waited to see if they got fixed. Now rc2 is out and I am worried all over again...

I for some reason do not have direct access to the database so I am very paranoid about experimenting with a database mod that I may have trouble repairing if I ooops. The code from Unknown should be safe to use to mod the database, but I have to write it in an installer to even try it.

I will review my notes and see if I am up to trying it.

Senkusha

Sorry for the resurrection!

I've tried to apply all these modifications (Along with a Gender restriction), and I think everything is working, but when I modify the board it appears that the data for age_min and gender_sel (my two columns) are not being populated on the form from the database.  The reason I know this is becuase I have a board that is set for 18 years old in the database, and for my gender restriction it is supposed to default to a value of "unrestricted" which is a value of -1.  Instead, the value is filling with "unspecified gender" (0).

Where are these values read?

I've looked in ManageBoards.php, Subs-Boards.php, and Load.php, but I think I'm missing something!  Help!! 

If I can sucessfully get this working, I'll give a shot to making this a MOD.....although, I'll probably need more help at that point, since I've never created the XML file before.)

Thanks!
--Senkusha
The Anime Brigade
Anime-style Role Playing Games and Discussion.
(SMF v. 2.1.4, PHP v. 8.0)

Furvert

#19
Sorry, I have done nothing on this for a year  :(

//add to load.php at end of function loadUserSettings(), place behind the original '$user_info['query_see_board']' related lines


//JH-Min_Age mod, calculate AGE just this once
if (empty($user_settings['birthdate']))
$AGE = 0;
else
{
list ($birth_year, $birth_month, $birth_day) = sscanf($user_settings['birthdate'], '%d-%d-%d');
$datearray = getdate(forum_time());
$AGE = empty($birth_year) ? 0 : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day)) ? 0 : 1);
}
if !($user_info['is_admin'])
$user_info['query_see_board'] .= ' AND b.Min_Age <= ' . (int) $AGE;//JH-Min_Age Mod with help by [Unknown]
//JH-MinAge mod-end


That should implement the age minimum for all boards with zero other impact.
Assuming you added that field to the boards table.

[Unknown] said before that running a command like this will add the field

db_query("
   ALTER TABLE {$db_prefix}boards
   ADD COLUMN Min_Age tinyint(3) unsigned NOT NULL default 0", false, false);

I have not tried this yet, I have no direct database access so I have to be very carefull and do it like a mod would.

What I have not looked into was how to make the board edit page.
ManageBoards.php would need some sort of mod to allow the admin to set Min_Age
As a quick fix a direct edit via sql could be done if you know the board ID or if a category is all to be set the same.

If ID_CAT 2 is adult boards this could set all to Min_Age 18?

INSERT INTO {$db_prefix}boards
(`ID_CAT`, 'Min_Age')
VALUES (2, 18),


But I need to look into making the editting mod

Senkusha did you add that field to the database with a wrong type?
Unsigned for example would not allow a -1 and thus default to 0?

db_query("
   ALTER TABLE {$db_prefix}boards
   ADD COLUMN gender_sel tinyint(3) unsigned NOT NULL default -1", false, false);

Signed would allow it

db_query("
   ALTER TABLE {$db_prefix}boards
   ADD COLUMN gender_sel tinyint(3) NOT NULL default -1", false, false);


Advertisement: