News:

Want to get involved in developing SMF, then why not lend a hand on our github!

Main Menu

need example for how to add mod configuration settings to admin cpanel

Started by Deprecated, August 11, 2008, 04:03:19 PM

Previous topic - Next topic

Deprecated

I want to add the following settings for my modification to the Admin -> Configuration -> Modifications:

Basically I need 1 or maybe 2 text boxes where I can add a comma separated list of integers. Examples

2
2,1, 3
4, 5, 6,7

I can't find any mod packages that do that. I guess I'll start looking in the base code, but wondered if anybody knew where I could find an example. Examples are always great particularly if they are small ones.

Deprecated

I'm going to add a bit more just so that any possible helper can understand what I'm trying to accomplish. I have a modification working, one I think a few people may even like, and in the modification I have a test. I've hard coded it for the present to check my modification and the mod works fine. Here is the test being performed:

in_array($variable, array(3, 4, 5, 6))

Based upon that the mod takes some action, but only when $variable is 3, 4, 5 or 6. But the mod is no good since those numbers are hard coded in, and every user will want to pick different numbers. So I need to add a configuration to the admin control panel something like this:

selected numbers = [7, 2, 3,4, 99       ]

I've just shown the box with some random numbers I picked. I have to get those numbers from the user and when he hits "save" I have to store them in the db where they will be available to my mod.

So I'll appreciate if anybody can point me to an example. I think the necessary code would be more than could be conveniently posted in CODE bbc tags here, but maybe not.

I've already adding some of the stuff to get my configuration to show up in the admin cpanel but it's not working yet, so it's got bugs.

TIA!

ccbtimewiz

This may or may not help you, but...

Have a field in the admin panel that feeds to an option. Something like @$modSettings['whatever'].

And have in that array check,

$x = array($modSettings['whatever']);
if( in_array( $x, $variable ) ) { }

Maybe that will assist you. It's basically what I did to create my Skype and Google Talk fields.

karlbenson

The format for adding to the Modifications section in the ADMIN area is exactly the same as for the ModSettings.php in 1.1.x
ModSettings.php has an explanation of all the different field types.

This is the code I used in the Forum Epoch mod (not yet approved, and is being released by ChristiceHurst)

<file name="$sourcedir/ManageSettings.php">
<operation>
<search position="before"><![CDATA[ // Mod authors, add any settings UNDER this line. Include a comma at the end of the line and don't remove this statement!!]]></search>
<add><![CDATA[
array('check', 'forum_epoch_enable'),
array('text', 'forum_created', '20',
'subtext' => $txt['forum_created_desc']. ' '. forum_epoch(false, true), 'forum_created'),
]]></add>
</operation>
<operation>
<search position="after"><![CDATA[ // This line is to help mod authors do a search/add after if you want to add something here. Keyword: FOOT TAPPING SUCKS!]]></search>
<add><![CDATA[

// Start of Forum Epoch mod

// Allow the field to be cleared, in order to force a reset
if(empty($_POST['forum_created']))
$modSettings['forum_created'] = 0 ;
$_POST['forum_created'] = empty($_POST['forum_created']) ? forum_epoch(true, false) : intval($_POST['forum_created']) ;
$_POST['forum_created'] = $_POST['forum_created'] < 0 || strlen($_POST['forum_created']) !== 10 || $_POST['forum_created'] > 2147483646 ? 0 : $_POST['forum_created'] ;

// End of Forum Epoch mod

]]></add>
</operation>
</file>


Although the above doesn't tie into profile section,

Deprecated

I'm sure that code will be a big help. I've been leery of looking at the 1.x mods because at my stage of familiarity (little) I wouldn't know what is 1.x and what will work with 2.x. Thanks for the code fragment. I'm gonna study it as soon as I post.

One question, I'm not sure that you mean about tying into the profile section. Not sure what a profile section is.

ETA:

Actually that's where I was digging. My stuff just doesn't work. I'm not even sure what the correct type of user interaction I should use.

Here's the two sections I was trying to add to:
// Mod Authors for a "ADD AFTER" on this line. Ensure you end your change with a comma. For example:

// Mod authors, once again, if you have a whole section to add do it AFTER this line, and keep a comma at the end.

karlbenson

I mentioned that it doesn't alter the profile (add a profile option for users) as you mentioned that
Quote[...] every user will want to pick different numbers

Also I want to make the point that was unclear.
Adding a setting to features/options as per 1.1.x is done in ModSettings.php
(where there is an explanation of adding a setting)
The Modifications section in admin is done via ManageSettings.php (which as you'd expect didn't exist in 1.1.x)

Deprecated

My modification has nothing to do with users or profiles.


And yeah, ManageSettings.php is the file that I'm screwing up at the moment. :)

It's just so complicated with nothing to compare it with. I've only been looking at the SMF code a week and it gets pretty obtuse at times.

Deprecated

Karl, thanks for the code snippet. I'm going to try putting my stuff in the same areas that you pointed out, see if that gets it started.

I think I was trying to create a new tab instead of just going under the common mods section, but I had better wait until I get the simple stuff going before I try the more difficult stuff.

You probably remember back when you first started writing code for SMF, right?

Deprecated

With your help Karl this is moving along really nicely, and I surely would not have made as much progress without your help. I've implemented my code based upon the same targets as your example above. Here's my code:


array('text', 'deprecated_text_1', '20'),
array('text', 'deprecated_text_2', '20'),


if(empty($_POST['deprecated_text_1'])) $modSettings['deprecated_text_1'] = 0 ;
if(empty($_POST['deprecated_text_2'])) $modSettings['deprecated_text_2'] = 0 ;


My options are showing up under the Modifications tag, and I can enter and save values. The only problem is that even with the if(empty) code I cannot clear my stored values. In addition to the above I also tried setting them to '' but that failed too. Why can't I clear my values?

Also, I've looked for where these are stored in the database and cannot find them. I know they're there because they stay set even if I close my browser, so I know they're stored in the db. I just can't find them.

I think my mod is nearly working! :)

karlbenson


Deprecated

I'm applying my edits via mod package, not direct FTP. But I'll try clearing the cache and see if that helps.

ETA: No, clearing the cache did nothing.

Deprecated

I'm curious for a little advice here. Besides the fact that I can't clear that db setting, which would be nice to know how.

My ultimate need for this setting is to compare an integer to see if it's in an array, e.g.:

if (in_array($n, array(2, 3, 9, 99)) except my array is the string entered in the admin cpanel, "2, 3, 9, 99" which is a character string.

I've had enough fun exploding and imploding strings but I wonder where and when to do this, and what to do. What is the best way to take an alpha string and get it into a form to compare against an integer using in_array() ?

[SiNaN]

And this is from my latest mod, not approved yet:

$request = db_query("
SELECT ID_GROUP, groupName
FROM {$db_prefix}membergroups", __FILE__, __LINE__);
while ($row = mysql_fetch_assoc($request)) {

$checked = false;

if(!empty($modSettings['rate_excludeGroups']) && in_array($row['ID_GROUP'], explode(',', $modSettings['rate_excludeGroups'])))
$checked = true;

$context['member_groups'][] = array(
'id' => $row['ID_GROUP'],
'name' => $row['groupName'],
'checked' => $checked,
);
}
mysql_free_result($request);

if (isset($_GET['save']))
{
if (!empty($_POST['member_groups']) && is_array($_POST['member_groups']))
$_POST['rate_excludeGroups'] = implode(',', $_POST['member_groups']);
else
$_POST['rate_excludeGroups'] = '';

$save_vars = $config_vars;
$save_vars[] = array('text', 'rate_excludeGroups');

saveDBSettings($save_vars);
redirectexit('action=rateadmin;sa=defaultsettings');
}


See the 'rate_excludeGroups' index. First I load all the groups, then check if the goup is in the $modSettings['rate_excludeGroups'] with exploding it.

And while saving, I implode it and put the groups into the $_POST variable, in the index which I want to save it as.

Hope I understand your issue correctly.
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

LoLoL, I hope I understand your reply correctly. I've just woke up out of a sound sleep on the 4th day of quitting coffee so I think it's best if I defer consideration until I wake up. Thanks Sinan for giving me your example.

I think what I'm doing is collecting an alpha string of comma separate numbers, but my code wants an array of integers to do its work. I think the best way to do it is to convert it once before it is stored in the db, so that it doesn't have to keep being converted every time it is used. Well the PHP website is pretty good, and maybe later in the morning when I wake up I'll be able to understand the example.

I do  not recommend quitting coffee. It's bad. Not sleeping is worse.

[SiNaN]

Okay, here comes another:

I have text field in modSettings, the admin will add the IDs of users to ban there seperated with a comma.

So just this code will create the text field for him in $config_vars:

array('text', 'banned_users'),

This is enough for modSettings.

So how do I use that in index.php file?

I'll just add $modSettings in globals and use this code:

if(!empty($modSettings['banned_users']) && in_array($context['user']['id'], explode(',', $modSettings['banned_users']))
die('You\'re banned, sorry.');
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

That sorta looks familiar. Explode the array on comma to compare $context[compare user][id] with each piece (in_array).

I can give that a try. It doesn't look too computationally expensive and IIRC an alpha string with a number in it is more or less treated by PHP as a number during numeric comparisons.

Now if I can just figure out why I can't clear my setting in the admin panel.

[SiNaN]

Yeah, the banned users are set like this for example: 45,76,234,676 and just you explode it before using.

Hmmm, you added a field, saved the setting and now cannot clear it? They are in the smf_settings table if it helps.
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

Yeah, thanks, I finally did find them in smf_settings this morning. They are going in okay, but I don't know why I can't clear them. That's what this line is supppsed to do:

f(empty($_POST['deprecated_text_1'])) $modSettings['deprecated_text_1'] = 0 ;

[SiNaN]

$modSettings array is filled in from db in Load.php, it doesn't effect db.

Use this instead while saving:

if(empty($_POST['deprecated_text_1']))
$_POST['deprecated_text_1'] = 0;
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

Purrrrrrrfectttt!!!!! (almost) :D

That was the way to go for sure, and it started working fine when I used the empty value of '' instead of 0.

Sinan, you da man! I really appreciate your taking this SMF-challenged, recycled C++ programmer through getting it done in PHP on SMF's platform.

Now all I have to do is use the stuff stored in the database over where my mod actually goes into action, and I think I'm a bit more familiar with how to do that, explode on comma, implode, etc. I've done that before in PHP when I was writing the search engine for my vanity site.

I think I'm nearing completion on this mod and hoping to send it to the modsite either today or in the next few days. Thanks for the help! :) Thanks also to Karl for the earlier help! :)

[SiNaN]

Not at all, you're always welcome. Would be glad if you mark the topic solved if you get it working. ;)
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

Just another question Sinan, on a higher level. Should I explode my array while ManageSettings is still running, like explode on comma, then clean it up, implode it to get a purely numeric array, then store that in the database? I'm wondering if that's what that code snippet you gave me does.

In the same area I'm in, can I store a third value calculated upon the entered values? And can that value be an array of integers?


And I was holding off marking it solved until I'm fully sure I'm done, probably a few hours from now.

Deprecated

Actually I think I want to explode on comma, then unset any space elements, and store the result as an array. It should be an array of just the numbers, right? Can you store that in the db?

[SiNaN]

That example was actually different. But this should help you with your question:

// Check if it is filled in.
if(!empty($_POST['deprecated_text_1'])) {

// Okay, get ready for checking; convert to an array
$values = explode(',', $_POST['deprecated_text_1']);

// Make sure every entry is integer.
foreach ($values as $index => $value)
$values[(int) $index] = (int) $value;

// Sum all the ids and add to the end
$values[] = array_sum($values);

// Ready to go! WHOOO HOOOO!
$_POST['deprecated_text_1'] = implode(',', $values);
}
else {
// No luck, just return 0.
$_POST['deprecated_text_1'] = 0;
}
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

Your example is imploding it back into a CSV list. I'd rather instead save a third value as the array of numbers, and just let whatever the user typed in stay as is. Here's my idea but it's not finished.


$no_spaces = str_replace(" ", "", $deprecated_text_1);
$pieces = explode (",", $no_spaces)

foreach ($pieces as $key => $>value) if ($value == "") unset $pieces[$key];

$deprecated_array_1 = $pieces;

// and then how do I tell save settings to save it?

First I strip the spaces, then I explode on comma, then I delete the null elements. At that point I should have an array with just the numbers. I hope I can store that in yet another variable that is not exposed to the user directly. Can that be done?

[SiNaN]

In your codes, do not forget to make sure things between commas are integer too.

You mean adding a setting without asking the admin? Just would calculate something with admin entered and save it into the db for further use, right?
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

What I want to do is take the two CSV strings of numbers and explode them and get rid of anything that isn't the actual integers the user entered, then I want to store those as an array of integers. The strings would also be stored, so that when the settings are changed next time the user sees what he had entered before.

The guts of my modification needs an array of integers to work on, and I don't want to calculate it every time it is used. It's better to make the array once when the admin is updating his selection, and then the stored array can be used in the test.

So the user (admin) enters two alpha fields of CSV numbers, but the cpanel stores an alpha string for each, and stores a corresponding array of integers for each also.

[SiNaN]

You talk too complex for me to understand it. I can say that I am a noob in programming.

What I understand is, you want to store old value too.
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

Okay, the way I have it now, the admin enters a series of comma separated integers. But my ultimate use requires an array of integers, not a character string. But I still want to store the character string so that next time the admin wants to view or modify the settings he sees the same thing he entered before, what I called deprecated_text_1 and deprecated_text too. That part is already working.

Now since my modification needs an array of integers to do its job, and since I don't want to explode the character string every time it's used (wasteful of CPU time) I want to do that just once as it's entered, and store the numeric arrays of integers as values that the admin does not need to see. Same information different form.

So I strip the spaces, explode on comma, get rid of any null elements (I've seen null elements when I've done this before) and then I store the arrays as separate variables.

What I don't understand is how to tell SMF to save my two arrays. SMF handles the character strings okay, but I have to tell SMF to include my two arrays and save them too.

Yeah, I know, I talk funny. :)

[SiNaN]

I don't know and just asking; how can you store it as an array in db?

If you just don't want to explode it again and again we can add a simple hack in Load.php to explode it automatically when he gets it.
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

I'm very, very thin on DB use. I've written only one piece of software that used a DB and I had about 5 calls to it. Use of DBs is probably my weakest area.

I had assumed you could store an array in a DB, and I'm sure you can but I guess not as one value. After all, smf_members is an array.

So I'll fall back and just store the CSV list, and then I'll explode it into an array at time of use. I'm probably being overly picky at trying to optimize for speed.

[SiNaN]

If you want, you can create your own table as smf_members but then you will need an sql query to get the values.

Even if we explode it in Load.php -where it's loaded- it will cause it be done on everypage; even in the ones that you don't use it.

In one function you just need to explode it once; so that's not something hard I guess. So I suggest sticking with the usual.
Former SMF Core Developer | My Mods | SimplePortal

Deprecated

The smf_members was just an example. I'm not doing anything with that.

I'll stick to the usual. :)

Deprecated

I'm pleased to say, my modification is done, it works, in fact it works ****ing perfectly!!! :D

Thank you all for the help and a special thanks to Karl and Sinan!

I need to run some tests and try to break the mod and use it on my production site for a couple days just to make sure it causes no problems, and then I'll upload it to the mod site mothership. :)

This is really gonna be kewl and it's my biggest mod to date!

Advertisement: