Reputation: 851
So, I have an array that has 6 variables in it that I need to check against each other.. to determine what to return to the script calling the function.. All fields are of the datetime
type from the database they are derived from.
the fields: in1
out1
in2
out2
in3
out3
Array:
Array(
'in1' => '2012-04-02 10:00:00),
`out1` => '2012-04-02 14:00:00`,
`in2` => '2012-04-02 14:30:00`,
`out2` => '2012-04-02 18:00:00`,
`in3` => NULL,
`out3` => NULL
)
the response:
clocked_in
or clocked_out
What I need to figure out is, the best way to determine if the user is clocked in or clocked out by checking against this array..
so, if in1
, out1
and in2
are not NULL then the user would be clocked in.. if in1
is not NULL but out1
is NULL then the user would be clocked out, etc.. Anyone have any ideas on the easiest way to achieve this without too many if statements?
[WHAT WORKED]
for ($i=1; $i <= 3; $i++) {
if ($entities["in$i"] != NULL) {
$ents = "clocked_in";
if ($entities["out$i"] != NULL) {
$ents = "clocked_out";
}
if ($entities["out3"] != NULL) {
$ents = "day_done";
}
}
}
Upvotes: 0
Views: 179
Reputation: 3633
Here's a more stylish way of doing it, without nests:
# the fields as array $a: in1 out1 in2 out2 in3 out3
function is_clocked_in( $a ) {
$c = (count(array_intersect( $a, array(null) ))) % 2;
return( $c ? true : false );
}
Theory behind this is that number of null fields gets returned by array_intersect; after that, you find out it that number is even or odd, which implies the clocked-in/out state. Example uses "t" to signify a non-null value, but it's meant to be a string timestamp.
var_dump( is_clocked_in( array( null, null, null, null, null, null ) ) ); // f
var_dump( is_clocked_in( array( "t", null, null, null, null, null ) ) ); // T
var_dump( is_clocked_in( array( "t", "t", null, null, null, null ) ) ); // f
var_dump( is_clocked_in( array( "t", "t", "t", null, null, null ) ) ); // T
var_dump( is_clocked_in( array( "t", "t", "t", "t", null, null ) ) ); // f
var_dump( is_clocked_in( array( "t", "t", "t", "t", "t", null ) ) ); // T
var_dump( is_clocked_in( array( "t", "t", "t", "t", "t", "t") ) ); // f
Upvotes: 1
Reputation: 581
What you should do is treat them as pairs. You should loop through your array two at a time checking to see if the clock in is set, and if so, is the clock out set. Update a variable along the way to make sure.
$clocked = '';
for($i=0; $i <= sizeOf($arr); $i+2) // $arr is your array of clock in and outs
{
if(arr[$i] != NULL)
{
// Our Clock In is Not Null and Our Clock Out is.. meaning we're clocked in.
if(arr[$i+1] == NULL) // check clock out
{
$clocked = "clocked in";
break; //Break out so we don't check the other pairs because we know we're clocked in.
}
else //Clock Out Exists, so far we're clocked out.
{
$clocked = "clocked Out"; // We can't break here. There might be more clock in/out pairs left to check.
}//end clock out check
}// end clock in check
}// end for loop
echo $clocked;
Its kinda rough as I wrote this up pretty quickly. I apologize if there are any syntax errors but this is the basic concept I'd use.
Upvotes: 1
Reputation: 20612
Perhaps a solution is at the schema level; you could modify the database to be an activity log, instead of using a concrete series of columns:
CREATE TABLE IF NOT EXISTS `mydb`.`Occurrence` (
`ID` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`OccurredOn` DATETIME NOT NULL ,
`Type` ENUM('IN','OUT') NOT NULL ,
PRIMARY KEY (`ID`) )
ENGINE = InnoDB
(forgive the brevity)
Now you can support an arbitrary number of clock-in/out occurrences, in the event requirements change.
Finding the state of a user is just selecting the most recent occurrence record, and checking the Type
field.
You can validate at the application level, such that if the most recent occurrence state is IN
, then you can only insert an OUT
, and vice versa.
Use a trigger to auto populate the DATETIME
field, or use TIMESTAMP
with CURRENT_TIMESTAMP
as the default (though I forget the specifics of that)
Upvotes: 0