I am building a page which allows our members to select their notification preferences based on a number of options. For example sake, I am giving the option for the member to select notifications when a new message arrives and when an update has occured. They can receive the notification via email, sms, both, or neither.
If I simply build it out as a number of:
HTML code
<tr>
<td>Alert me when a new message comes in:</td>
</tr>
<tr>
<td>
<label><input name="ENREME" type="radio" style="margin-left:30px;" value="EMAIL" <?php if ($smscode == "7" || $smscode == "4") { ?>checked="checked"<?php } ?> tabindex="15" />Email</label>
<label><input name="ENREME" type="radio" style="margin-left:30px;" value="SMS" <?php if ($smscode == "7" || $smscode == "5") { ?>checked="checked"<?php } ?> />SMS</label>
<label><input name="ENREME" type="radio" style="margin-left:30px;" value="BOTH" <?php if ($smscode == "7" || $smscode == "6") { ?>checked="checked"<?php } ?> tabindex="15" />Both</label>
<label><input name="ENREME" type="radio" style="margin-left:30px;" value="NONE" <?php if ($smscode == "0") { ?>checked="checked"<?php } ?> />Don't notify me</label>
</td>
</tr>
<tr>
<td>Alert me when a new update to my site occurs:</td>
</tr>
<tr>
<td>
<label><input name="RECRUITEME" type="radio" style="margin-left:30px;" value="EMAIL" <?php if ($smscode == "7" || $smscode == "1") { ?>checked="checked"<?php } ?> tabindex="15" />Email</label>
<label><input name="RECRUITEME" type="radio" style="margin-left:30px;" value="SMS" <?php if ($smscode == "7" || $smscode == "2") { ?>checked="checked"<?php } ?> /> SMS</label>
<label><input name="RECRUITEME" type="radio" style="margin-left:30px;" value="BOTH" <?php if ($smscode == "7" || $smscode == "3") { ?>checked="checked"<?php } ?> tabindex="15" />Both</label>
<label><input name="RECRUITEME" type="radio" style="margin-left:30px;" value="NONE" <?php if ($smscode == "0") { ?>checked="checked"<?php } ?> />Don't notify me</label>
</td>
</tr>
<?php
if ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "BOTH") {
$notif = 15;
} elseif ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "SMS") {
$notif = 14;
} elseif ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "EMAIL") {
$notif = 13;
} elseif ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "NONE") {
$notif = 12;
} elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "BOTH") {
$notif = 11;
} elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "SMS") {
$notif = 10;
} elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "EMAIL") {
$notif = 9;
} elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "NONE") {
$notif = 8;
} elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "BOTH") {
$notif = 7;
} elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "SMS") {
$notif = 6;
} elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "EMAIL") {
$notif = 5;
} elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "NONE") {
$notif = 4;
} elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "BOTH") {
$notif = 3;
} elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "SMS") {
$notif = 2;
} elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "EMAIL") {
$notif = 1;
} elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "NONE") {
$notif = 0;
}
?>
I am left to code for 16 possible variables (and thus creating over 100 lines of code). Can anybody think of a better way to consolidate this code? Based on the selections made, I want the result to equal a single digit (i.e. 28 equals, send email and SMS notifications for both new messages and updates).
Creating a new table or database and making reference calls is not a solution so please do not suggest that.
Thank you!
It sounds like what you're really looking for is a bitwise solution. Using bits, you're able to store a lot of boolean switches into a single integer. This answer uses some roundabouts to keep things clear - you could use the int values directly instead of the pow(2,X) shown below... consider it "teaching a man to fish".
If you'd like a more succint, though complex to understand solution, take a look at Ast Derek's answer. They both do the same thing and operate on the same principle.
In order to store these, let's do two simple switches:
switch($_GET['x']) {
case 'Email': $x = pow(2,0); break; // 1
case 'Sms': $x = pow(2,1); break; // 2
case 'Both': $x = pow(2,0) + pow(2,1); break;// 3
default: $x = 0;
}
switch($_GET['y']) {
case 'Email': $y = pow(2,2); echo "Y Email"; break; // 4
case 'Sms': $y = pow(2,3); echo "Y SMS"; break; // 8
case 'Both': $y = pow(2,2) + pow(2,3); echo "Y Both"; break; // 12
default: $y = 0;
}
As you can see, the None options are absent. None is simply the absence of a either Email or SMS. Also, the Both option is defined not as a separate option, but as a combination of both.
Now that we have these value, we can combine these two numbers into a single number, since their relevant bits are both in different ranges.
$z = $x | $y;
What happens when looking at the bits is the following - assume that we've got X = Email, and Y = Both.
x = 0001 -> (0 + 0 + 0 + 1) -> 1
y = 1100 -> (8 + 4 + 0 + 0) -> 12
-----
OR: 1101 -> (8 + 4 + 0 + 1) -> 13
What this will give you is the following possible results:
0: x = none, y = none
1: x = email, y = none
2: x = sms, y = none
3: x = both, y = none
4: x = none, y = email
5: x = email, y = email
6: x = sms, y = email
7: x = both, y = email
8: x = none, y = sms
9: x = email, y = sms
10: x = sms, y = sms
11: x = both, y = sms
12: x = none, y = both
13: x = email, y = both
14: x = sms, y = both
15: x = both, y = both
To detect which have chosen, simply reverse the operation.
So you can test things, I've put the whole setup in a Github Gist for you to enjoy and tinker with: http://gist.github.com/505272
Feel free to ask if you need clarification; I'm not sure I explained it very clearly :/
This is an example on how NOT knowing C puts you against a wall when developing simple things. As far as I can see, the simplest option is the best, just use binary!:
define('SEND_EMAIL',1);
define('SEND_SMS',2);
/* The values are packed together, low bits represent 'update' options,
* high bits represent 'message' options
* You can save up to 4 variants (ON/OFF) with 0xf
*/
$options = ((intval($_POST['message']) & 0xf) << 4) | (intval($_POST['update']));
...
// Retrieve options from, say, stored option
$message = ($options >> 4) & 0xf;
$update = $options & 0xf;
/* For readability, this can be a function */
if ($message == (SEND_SMS|SEND_EMAIL)) {
$message = 'Both';
}
else if ($message == SEND_SMS) {
$message = 'SMS';
}
else if ($message == SEND_EMAIL) {
$message = 'Email';
}