Settings Control Panel Question

Started by The Wizard, March 23, 2013, 07:02:39 AM

Previous topic - Next topic

The Wizard

Hello:

I'm thinking of adding a settings control panel to the next version of my mod and was going to use checkboxes.
So here is my question - Is there a easy way to save the data without having to write to the database?

Just so you all know I'm coding SMF 2.0.4.

Thanks

Wiz

Kays

If you use the "show_settings" template then it's done automatically. In fact you don't even need to create the template.

Take a look in ManageServer.php. There's a bit of a description on the available options at the beginning. Then look at the second function for an example. All that's required is the one line for the setting and a $txt string to match up with that setting.

If at first you don't succeed, use a bigger hammer. If that fails, read the manual.
My Mods

The Wizard



$txt['new_years'] = 'New Years';

array('new_years', $txt['new_years'], 'file', 'check')

   
OK I am confused somewhat here. Your saying I don't have to create my own template so I just add that small code above to my php page and it will create a template, store the information somewhere and allow me to call it up when I need it?

This sounds way too simple.

Wiz

   

Kays

Yes it is a quite simple. to do. :)

Since this is to be a separate page you will need to add a button for it in the admin cp. So create a separate function for this settings page. Use the second one in ManageServer.php as a template and add your checkboxes to that Then point your button to that function.

If at first you don't succeed, use a bigger hammer. If that fails, read the manual.
My Mods

Arantor

You're looking at the wrong function - that's one using prepareServerSettingContext, which really should not be used directly unless you're modifying something in the *few* pages that need it.

Look at any function in ManageServer that uses prepareDBSettingContext instead, e.g. the anti spam page, or features and options...

The Wizard

Arantor:

I tryed to find anti spam page, or features and options in the ManageServer.php but I can't seem to find them. I did find the code below with the function prepareDBSettingContext in it. However if I just cut and paste that into a php page and call the function I get this error -

QuoteFatal error: Call to undefined function prepareDBSettingContext() in /home/content/05/9199905/html/SMF-Mod-Test-Area/Sources/banner/HolidaySettings.php on line 100

I expect I'm missing something here.

Wiz


Function HolidaySettings($return_config = false)
{
global $txt, $scripturl, $context, $settings, $modSettings;

// Setup a warning message, but disabled by default.
$disabled = true;
$context['settings_message'] = $txt['loadavg_disabled_conf'];

if (strpos(strtolower(PHP_OS), 'win') === 0)
$context['settings_message'] = $txt['loadavg_disabled_windows'];
else
{
$modSettings['load_average'] = @file_get_contents('/proc/loadavg');
if (!empty($modSettings['load_average']) && preg_match('~^([^ ]+?) ([^ ]+?) ([^ ]+)~', $modSettings['load_average'], $matches) !== 0)
$modSettings['load_average'] = (float) $matches[1];
elseif (($modSettings['load_average'] = @`uptime`) !== null && preg_match('~load averages?: (\d+\.\d+), (\d+\.\d+), (\d+\.\d+)~i', $modSettings['load_average'], $matches) !== 0)
$modSettings['load_average'] = (float) $matches[1];
else
unset($modSettings['load_average']);

if (!empty($modSettings['load_average']))
{
$context['settings_message'] = sprintf($txt['loadavg_warning'], $modSettings['load_average']);
$disabled = false;
}
}

// Start with a simple checkbox.
$config_vars = array(
array('check', 'loadavg_enable'),
);

// Set the default values for each option.
$default_values = array(
'loadavg_auto_opt' => '1.0',
'loadavg_search' => '2.5',
'loadavg_allunread' => '2.0',
'loadavg_unreadreplies' => '3.5',
'loadavg_show_posts' => '2.0',
'loadavg_forum' => '40.0',
);

// Loop through the settings.
foreach ($default_values as $name => $value)
{
// Use the default value if the setting isn't set yet.
$value = !isset($modSettings[$name]) ? $value : $modSettings[$name];
$config_vars[] = array('text', $name, 'value' => $value, 'disabled' => $disabled);
}

if ($return_config)
return $config_vars;

$context['post_url'] = $scripturl . '?action=admin;area=serversettings;sa=loads;save';
$context['settings_title'] = $txt['load_balancing_settings'];

// Saving?
if (isset($_GET['save']))
{
// Stupidity is not allowed.
foreach ($_POST as $key => $value)
{
if (strpos($key, 'loadavg') === 0 || $key === 'loadavg_enable')
continue;
elseif ($key == 'loadavg_auto_opt' && $value <= 1)
$_POST['loadavg_auto_opt'] = '1.0';
elseif ($key == 'loadavg_forum' && $value < 10)
$_POST['loadavg_forum'] = '10.0';
elseif ($value < 2)
$_POST[$key] = '2.0';
}

saveDBSettings($config_vars);
redirectexit('action=admin;area=serversettings;sa=loads;' . $context['session_var'] . '=' . $context['session_id']);
}

prepareDBSettingContext($config_vars);
}

Arantor

* Arantor buries head in hands, remembering why he shouldn't offer support.

Look at the entire execution from the point it leaves Admin.php, most of the settings pages call a helper function to do some initialisation. Most of the time this will load ManageServer.php, which is where that function is declared.

It would be helpful to look at other code that does similar jobs and understand why it does what it does, your HolidaySettings code will do a very great many things to it that you SHOULD NOT BE DOING. Like screwing up the load average settings in the process.

Please do not copy/paste code without understanding what it's actually doing.

The Wizard

Well we both agree on something - I have no idea what the hell I'm doing (at least with this code), and I'm sorry to have been a disappointment again.

I should have gone with the path I knew. I know how to make a form and get the results form it and I know how to write to the database. I was just hoping to find a simpler way as I'm just talking about check boxes here.

Wiz
 




Arantor

That isn't quite what I meant. You don't know what you're doing - right now. Instead of running headlong, go back and look at the code and ask yourself what each line does.

The Wizard

Hello:

I have gone back and reviewed how each line works, and below is a rough draft of HolidaySettings.php.
However I still get the following error -
QuoteUnable to load the 'main' template.
I think the problem is
Quotearea=
or
Quotesa=
as I'm still shakey on what they do.
I have also include my Subs-Admin-Banner-Hooks.php.

Note: I have included the folowing code:

$txt['enable_halloween'] = '<strong>Halloween:</strong>';
$txt['holiday_title'] = 'Holiday Settings';


for ease of use. I am fully aware where it should go. As I said before this is just rough draft to get the mechanics of how this works down.

Thanks

Wiz

Subs-Admin-Banner-Hooks.php


function banner_admin_areas(&$admin_areas)
{
global $txt;

$admin_areas['monthlybanner'] = array(
'title' => $txt['banner_admin'],
'permission' => array('admin_forum'),
'areas' => array(
'holiday_settings' => array(
'label' => $txt['holiday_settings'],
'file' => 'banner/HolidaySettings.php',
'function' => 'HolidaySettings',
),
'banner_add' => array(
'label' => $txt['banner_add'],
'file' => 'banner/BannerAdd.php',
'function'=> 'BannerAdd',
),
'banner_remove' => array(
'label' => $txt['banner_remove'],
'file' => 'banner/BannerRemove.php',
'function' => 'BannerRemove',
),
'holiday_add' => array(
'label' => $txt['holiday_add'],
'file' => 'banner/HolidayAdd.php',
'function' => 'HolidayAdd',
),
'holiday_remove' => array(
'label' => $txt['holiday_remove'],
'file' => 'banner/HolidayRemove.php',
'function' => 'HolidayRemove',
),
),
);
}


HolidaySettings.php


Function HolidaySettings($return_config = false)
{
global $context, $sourcedir, $txt, $scripturl, $modSettings, $settings;
require_once($sourcedir . '/ManageServer.php');
require_once($sourcedir . '/Subs-Admin-Banner-Hooks.php');

$txt['enable_halloween'] = '<strong>Halloween:</strong>';
$txt['holiday_title'] = 'Holiday Settings';

$config_vars = array(
array('check', 'enable_halloween'),
);

if ($return_config)
return $config_vars;

$context['post_url'] = $scripturl . '?action=admin;area=monthlybanner;sa=HolidaySettings;save';
$context['page_title'] = $txt['holiday_title'];

if (isset($_GET['save'])){

checkSession();
saveDBSettings($config_vars);
redirectexit('action=admin;area=monthlybanner;sa=HolidaySettings');
}

prepareDBSettingContext($config_vars);
}

Arantor

Quoteas I'm still shakey on what they do.

area and sa (subaction) are ways to break down the admin panel, seeing how huge it is.

area= something breaks it down into a set of pages, e.g. Admin > Members > Permissions is an area. sa= breaks it down into a specific page within that area.

The reason there is an error is because you haven't told it to use a given sub-template, in this case $context['sub_template'] = 'show_settings';

Like I said, look at other functions - most of them either set that directly, or there is a helper function called just before them, which is why you need to look at everything that happens from the point of Admin.php calling the relevant functions.

See what they do that yours is not. It's really that simple.

The Wizard

Hello:

This is what I have so far. Is there a quick way to test it?

Wiz


$txt['holiday_settings_title'] = 'Holiday Settings';
$txt['holiday_settings_new_years'] = '<strong>New Years</strong>';
$txt['holiday_settings_valentines'] = '<strong>Valentines</strong>';
$txt['holiday_settings_st_patricks']        = '<strong>St Patricks</strong>';
$txt['holiday_settings_easter'] = '<strong>Easter</strong>';
$txt['holiday_settings_april_fools']         = '<strong>April Fools</strong>';
$txt['holiday_settings_july_4th'] = '<strong>Independence Day</strong>';
$txt['holiday_settings_halloween'] = '<strong>Halloween</strong>';
$txt['holiday_settings_thanksgiving'] = '<strong>Thanksgiving</strong>';
$txt['holiday_settings_christmas'] = '<strong>Christmas</strong>';
$txt['holiday_settings_today'] = '<strong>Today (test)</strong>';

Function HolidaySettings($return_config = false)
{
global $context, $sourcedir, $txt, $scripturl, $modSettings, $settings;
require_once($sourcedir . '/ManageServer.php');

// Note: for some reason I don't understand the 'check' must come first or the text will not show up.
$config_vars = array(
array('check', 'holiday_settings_new_years'),
array('check', 'holiday_settings_valentines'),
array('check', 'holiday_settings_st_patricks'),
array('check', 'holiday_settings_easter'),
array('check', 'holiday_settings_april_fools'),
array('check', 'holiday_settings_july_4th'),
array('check', 'holiday_settings_halloween'),
array('check', 'holiday_settings_thanksgiving'),
array('check', 'holiday_settings_christmas'),
array('check', 'holiday_settings_today'),
);

if ($return_config)
return $config_vars;

$context['sub_template'] = 'show_settings';

$context['post_url'] = $scripturl . '?action=admin;area=holiday_settings;sa=HolidaySettings;save';
$context['page_title'] = $txt['holiday_settings_title'];

if (isset($_GET['save'])){

checkSession();
saveDBSettings($config_vars);
redirectexit('action=admin;area=holiday_settings;sa=HolidaySettings');
}

prepareDBSettingContext($config_vars);
}

Arantor

The only way to test it is to actually run it, i.e. installing the mod and trying to use it.

The Wizard

Quote from: Arantor on March 24, 2013, 04:20:36 PM
The only way to test it is to actually run it, i.e. installing the mod and trying to use it.

Sorry should have added more info my fault.

I have the mod installed on a test board with the new additions, and yes when I hit the settings button the template is created with the check boxes, and when I hit save it refreshes the screen with the boxes I chose checked.

What I was asking was how to you tell if the information was stored? and how do you call this information to use it in a php script?

Wiz

Arantor

You would check it is in the smf_settings table. The fact it is being saved suggests it really is in the database.

As far as using that, the values are in $modSettings, e.g. test that $modSettings['holiday_settings_new_years'] is empty or not. If it is empty, it was unticked, if it is not empty it is ticked.

The Wizard

Well it's all working now  :)

It was difficult to create my first control panel, but I did manage it.
Below is the code I used and hopefully seeing it will help other users.

If anybody knows a way to streamline it let me know.
I would love to streamline the if not empty $modSettings code in the BannerRotation.php, but I don't see a way myself.

Thanks Arantor for all the help. I know sometimes my brain can be as hard as concrete.

Wiz



HolidaySettings.php


Function HolidaySettings($return_config = false)
{
global $context, $sourcedir, $txt, $scripturl, $modSettings, $settings;
require_once($sourcedir . '/ManageServer.php');

// Note: for some reason I don't understand the 'check' must come first or the text will not show up.
$config_vars = array(
array('check', 'holiday_settings_new_years'),
array('check', 'holiday_settings_valentines'),
array('check', 'holiday_settings_st_patricks'),
array('check', 'holiday_settings_easter'),
array('check', 'holiday_settings_april_fools'),
array('check', 'holiday_settings_july_4th'),
array('check', 'holiday_settings_halloween'),
array('check', 'holiday_settings_thanksgiving'),
array('check', 'holiday_settings_christmas'),
array('check', 'holiday_settings_today'),
);

if ($return_config)
return $config_vars;

$context['sub_template'] = 'show_settings';

$context['post_url'] = $scripturl . '?action=admin;area=holiday_settings;sa=HolidaySettings;save';
$context['page_title'] = $txt['holiday_settings_title'];
$context['settings_title'] = $txt['holiday_settings_title'];

if (isset($_GET['save'])){

checkSession();
saveDBSettings($config_vars);
redirectexit('action=admin;area=holiday_settings;sa=HolidaySettings');
}

prepareDBSettingContext($config_vars);
}



BannerRotation.php


Function BannerRotation()
{
global $settings, $modSettings;

// Start Holidays

// Holiday List
if (!empty($modSettings['holiday_settings_new_years']))
{
$holidays = array('01 01' => 'New_Years');
}

if (!empty($modSettings['holiday_settings_valentines']))
{
$holidays = array('02 14' => 'Valentines');
}

if (!empty($modSettings['holiday_settings_st_patricks']))
{
$holidays = array('03 17' => 'St_Patricks');
}

if (!empty($modSettings['holiday_settings_easter']))
{
$holidays = array('03 21' => 'Easter');
}

if (!empty($modSettings['holiday_settings_april_fools']))
{
$holidays = array('04 01' => 'April_Fools');
}

if (!empty($modSettings['holiday_settings_july_4th']))
{
$holidays = array('07 04' => 'Independence_Day');
}

if (!empty($modSettings['holiday_settings_halloween']))
{
$holidays = array('10 31' => 'Halloween');
}

if (!empty($modSettings['holiday_settings_thanksgiving']))
{
$holidays = array('11 28' => 'Thanksgiving');
}

if (!empty($modSettings['holiday_settings_christmas']))
{
$holidays = array('12 25' => 'Christmas');
}

if (!empty($modSettings['holiday_settings_today']))
{
$date_test=date('m d');
$holidays = array($date_test => 'Today');
}

$date=date('m d');

if (isset($holidays[$date]))
{

// File path of where the Holiday Banners images are.
$holiday_dir_path = $settings['default_theme_dir'] . '/images/banners/holiday_images/big/';

// File path of where the Holiday Banners images are.
$holiday_url_path = $settings['default_theme_url'] . '/images/banners/holiday_images/big/';

// Read dir of Holiday Monthly Banner Images

$d = dir($holiday_dir_path);
while (false !== ($entry = $d->read()))
{
if ($entry != '.' && $entry != '..' && !is_dir($holiday_url_path . $entry))
$holiday_images[] = $entry;
}
$d->close();

// Figure out what Holiday
$holiday_date = $holidays[$date];

$holidays_extensions = array(
$holiday_date . '.jpeg',
$holiday_date . '.jpg',
$holiday_date . '.gif',
$holiday_date . '.png'
);

$k = count($holiday_images);

for ($x = 0; $x < $k; $x++)
{
if (in_array($holiday_images[$x], $holidays_extensions))
{
//Display Holiday Banner
echo '<br /><table border="1" width="1024" align="center"><tbody><tr><td width="1024" height="200" bgcolor="#000000">
<img border="0" src="', $holiday_url_path . $holiday_images[$x] . '" />
</td></tr></tbody></table><br />';
}
}
}
else
{
// Show Monthly Banner

// File path of where the uploaded images go.
$uploaddir = $settings['default_theme_dir'] . '/images/banners/banner_images/big/';

// File path of where the uploaded images go.
$url_path = $settings['default_theme_url'] . '/images/banners/banner_images/big/';

// File path of where the Holiday Banners images are.
$holiday_url_path = $settings['default_theme_url'] . '/images/banners/holiday_images/big/';

// Read dir Monthly Banner Images

$d = dir($uploaddir);
while (false !== ($entry = $d->read()))
{
if ($entry != '.' && $entry != '..' && !is_dir($holiday_url_path . $entry))
$Images[] = $entry;
}
$d->close();

// Figure out what Month it is. Calls imformation from server
$month          = date('F');
$possible_items = array(
$month . '.jpeg',
$month . '.jpg',
$month . '.gif',
$month . '.png'
);

$k = count($Images);

for ($i = 0; $i < $k; $i++)
{
if (in_array($Images[$i], $possible_items))
{
//Display Banner
echo '<br /><table border="1" width="1024" align="center"><tbody><tr><td width="1024" height="200" bgcolor="#000000">
<img border="0" src="', $url_path . $Images[$i] . '" />
</td></tr></tbody></table><br />';
}
}
}
// End of Show Monthly Banner
}

Arantor

Quote// Note: for some reason I don't understand the 'check' must come first or the text will not show up.

Because there are different kinds of items, some of which require more or less information. The only thing that is absolutely guaranteed to be there is the type of item you're doing.

QuoteI would love to streamline the if not empty $modSettings code in the BannerRotation.php, but I don't see a way myself.

I'm thinking the following. I haven't tested it, but there are some interesting changes to mull over and consider what that might mean, for example using foreach.

Function BannerRotation()
{
global $settings, $modSettings;

// Start Holidays
$holidays = array(
'01 01' => array('holiday_settings_new_years', 'New_Years'),
'02 14' => array('holiday_settings_valentines', 'Valentines'),
'03 17' => array('holiday_settings_st_patricks','St_Patricks'),
'03 21' => array('holiday_settings_easter', 'Easter'),
'04 01' => array('holiday_settings_april_fools', 'April_Fools'),
'07 04' => array('holiday_settings_july_4th', 'Independence_Day'),
'10 31' => array('holiday_settings_halloween', 'Halloween'),
'11 28' => array('holiday_settings_thanksgiving', 'Thanksgiving'),
'12 25' => array('holiday_settings_christmas', 'Christmas'),
);
$date_test=date('m d');
$holidays[$date_test] = array('holiday_settings_today', 'Today');

$date=date('m d');

if (isset($holidays[$date]) && !empty($modSettings[$holidays[$date][0]]))
{
// Figure out what Holiday
$holiday_date = $holidays[$date][1];

// File path of where the Holiday Banners images are.
$holiday_dir_path = $settings['default_theme_dir'] . '/images/banners/holiday_images/big/';

// File path of where the Holiday Banners images are.
$holiday_url_path = $settings['default_theme_url'] . '/images/banners/holiday_images/big/';

// Read dir of Holiday Monthly Banner Images

$d = dir($holiday_dir_path);
while (false !== ($entry = $d->read()))
{
if ($entry != '.' && $entry != '..' && !is_dir($holiday_url_path . $entry))
$holiday_images[] = $entry;
}
$d->close();

$holidays_extensions = array(
$holiday_date . '.jpeg',
$holiday_date . '.jpg',
$holiday_date . '.gif',
$holiday_date . '.png'
);

foreach ($holiday_images as $image)
{
if (in_array($image, $holidays_extensions))
{
//Display Holiday Banner
echo '<br /><table border="1" width="1024" align="center"><tbody><tr><td width="1024" height="200" bgcolor="#000000">
<img border="0" src="', $holiday_url_path . $image . '" />
</td></tr></tbody></table><br />';
}
}
}
else
{
// Show Monthly Banner

// File path of where the uploaded images go.
$uploaddir = $settings['default_theme_dir'] . '/images/banners/banner_images/big/';

// File path of where the uploaded images go.
$url_path = $settings['default_theme_url'] . '/images/banners/banner_images/big/';

// File path of where the Holiday Banners images are.
$holiday_url_path = $settings['default_theme_url'] . '/images/banners/holiday_images/big/';

// Read dir Monthly Banner Images

$d = dir($uploaddir);
while (false !== ($entry = $d->read()))
{
if ($entry != '.' && $entry != '..' && !is_dir($holiday_url_path . $entry))
$Images[] = $entry;
}
$d->close();

// Figure out what Month it is. Calls imformation from server
$month          = date('F');
$possible_items = array(
$month . '.jpeg',
$month . '.jpg',
$month . '.gif',
$month . '.png'
);

foreach ($Images as $image)
{
if (in_array($image, $possible_items))
{
//Display Banner
echo '<br /><table border="1" width="1024" align="center"><tbody><tr><td width="1024" height="200" bgcolor="#000000">
<img border="0" src="', $url_path . $image . '" />
</td></tr></tbody></table><br />';
}
}
}
// End of Show Monthly Banner
}

The Wizard

Wow that code worked perfectly, and yes it has given me allot of food for thought.  :)

Wiz

Advertisement: