views:

37

answers:

2

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>

Variable Encoding and Storage

<?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!

+1  A: 

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 :/

kander
@KANDER - thank you for the help! I am looking into your code now, trying to learn new things!
JM4
You're welcome :) Bitwise logic can be challenging, but once you get it, it will surprise you how often it comes in handy :)Also, consider looking into the MySQL SET type, since you'll be storing it in a database anyway. The SET type allows you to store values like these easily, and uses the same bitwise logic in the backend for efficient storage.
kander
+3  A: 

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';
}
Ast Derek
We arrived at the same conclusion for the answer - of course. I like how yours teaches more how to do it "properly", while mine focuses more on making sure the process is understood by not introducing shifts and hexadecimal variants. Both valuable lessons, and I'm sure between them, the asker will find what he needs :)
kander
@Ast Derek - Thank you for the solution. I am having a bit of trouble following and hope you can assist. Where do the $_POST['message'] and $_POST['update'] variables come from? Also - just to clarify, I want to store the result (integer from 0 to 15) in a database which I will use on other pages to generate outbound notifications (i.e. if members notification code = 14, send this email).
JM4
Ast Derek