- I strongly recommend that you change your functions so that they do not output anything (remove echoes and prints). This also takes care of the issue with functions jumping in and out of php parsing mode. While all this works, reading the code becomes difficult, since it tangles logic and presentation together.
- Why do you have stripslashes here and there in your code? Is magipc_quotes_gpc (GPC = GET POST COOKIES) turned on in php.ini? If so, disable it and escape things as needed for each particular purpose. I.e. use your db specific escape mechanism, such as mysqli::escape_string, when inserting strings into the database, htmlentities when outputting strings to a web page, urlencode when outputting strings in urls etc.
I havn't gone through all the code in depth due to the issue with entanglement of logic and presentation. But from what I understand I'd change pregwcalc_options into a function which checks if the user has stored an option selection in the db by calling pregwcalc_getuseroption(), and after that retrieves options from the database by calling pregwcalc_getoptions($selected_value). By passing on the selected value to getoptions, you can
SELECT same, fields, as_before, option_value = $selected_value AS selected
FROM ...
Then, when you output your options (NOT in this function), you simply check if the option was selected, see pregwcalc_renderoptions() further down. Handling the comparison in SQL works well if you're using PDO where you would not iterate over the result set, but simply call PDO::fetchAll() to get all rows. If you have to cycle over the result set to get all rows, you might want to drop the comparison from the query, and instead do it while iterating over the result set.
Finally, you may actually have functions that do output things, but then they should do nothing else. If you don't go with functions for this, do it in separate php pages. You should note that this approach means that you no longer have to distringuish between page and widget in any of your functions handling logic. It's only when you come to presentation that there will be a difference! Also, since the options as such are (probably) the same, output of the actual options can also be handled generically. Thus, only the rest of the page / widget has to be dealt with separately.
if ($widget)
{
pregwcalc_renderwidget($options);
}
else
{
pregwcalc_renderpage($options);
}
# and somewhere inside each of those functions, a call to
function pregwcalc_renderoptions($options)
{
foreach ($options as $o)
{
printf('<option value="%d"%s>%s</option>',
$o['value'],
$o['selected'] ? ' selected="selected"' : '',
$o['txt']
);
}
}
To use the exact same code when a user posts a new value, start by updating the database
$errors = array();
if (isset($_POST['submit_option']))
{
$o = $_POST['submit_option']
# whatever checks are necessary to assertain valid data
if (!is_numeric($o) || $o < 1 || $o > 53)
{
$errors[] = 'Unable to save data';
}
else
{
# INSERT / UPDATE here
}
}
# Reest of the code as shown earlier in my post comes here.
Finally, in each of the renderwidget and renderpage functions, add a new parameter $errors and wherever it's appropriate from a layout perspective add a call to
render_errors($errors);
A minor thing by the way, if someone else will ever look at your code, I'd change the naming from pregw to something else, like for example pw, since there is allready a preg_ family of functions. Or wrap all functions in a pregnancy_week namespace and drop the prefix alltogether.