Im not great at PHP but I typed up the following code to change the header image based on the date array I have set.
Im wondering if the code looks alright and will function as intended or if iv missed something in my coding.
$hollidayevents = array(
array(
'image' => 'wp-content/uploads/1.png',
'start' => '01-02',
'end' => '02-02'
),
array(
'image' => 'wp-content/uploads/2.png',
'start' => '03-02',
'end' => '04-02'
)
);
foreach($hollidayevents as $myevent) {
if(date('d-m') >= $myevent['start'] && date('d-m') <= $myevent['end']) {
echo "<img src='".$myevent['image']."'>";
}
else { echo "<img src='wp-content/uploads/default header image'>";}
}
When you compare the dates as string with 'd-m' format the result is based on the day and only if days are same then it comes to compare months too.
For example imagine this: '20-10' > '01-11', both are with format you used 'd-m' what is the result ? First is higher then second so the result is true, even tho you would expect the opposite. Thats because only first character gets compared.
$hollidayevents = array(
array(
'image' => 'wp-content/uploads/1.png',
'start' => '02-01', // <- m-d format
'end' => '02-02' // <- m-d format
),
array(
'image' => 'wp-content/uploads/2.png',
'start' => '02-03', // <- m-d format
'end' => '02-04' // <- m-d format
)
);
$eventFound = false;
foreach($hollidayevents as $myevent) {
if(date('m-d') >= $myevent['start'] && date('m-d') <= $myevent['end']) {
echo "<img src='".$myevent['image']."'>";
$eventFound = true;
break;
}
}
if(!$eventFound){
echo "<img src='wp-content/uploads/default header image'>";
}
Related
Forgive me, this is a long one. I want to give all the background for this question.
I am using DataTables server-side processing for a project. My goal is to utilize the echo function to echo the number of days between today's date and dates in a column of my database called CreatedDate, which is a DateTime type.
I was trying to get the basic functionality working outside of DataTables first, and the function below works as intended, and outputs an $current_date of the number of days between $date and $date as: "16 days live", "15 days live", etc.:
$sql = "SELECT CreatedDate FROM Estimates";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$created_date = $row["CreatedDate"];
$date = new DateTime($created_date);
$current_date = new DateTime();
$diff = date_diff($date, $current_date);
echo $diff->format('%d days live');
}
} else {
echo "No results";
}
In my DataTables $columns array, I am trying to achieve the same effect:
// date variable
$created_date = 'CreatedDate';
$current_date = new DateTime();
// array of database columns which should be read and sent back to DataTables.
// the 'db' parameter represents the column name in the database, while the 'dt'
// parameter represents the DataTables column identifier.
$columns = array(
array( 'db' => 'Client', 'dt' => 0 ),
array( 'db' => 'EstimateNumber', 'dt' => 1 ),
array( 'db' => 'Status', 'dt' => 2 ),
array( 'db' => 'CurrentEstimateTotal', 'dt' => 3 ),
array(
'db' => $created_date,
'dt' => 4,
'formatter' =>
function ($created_date, $row) use ($current_date) {
$date = new DateTime($created_date);
$diff = date_diff($date, $current_date);
echo $diff->format('%d days live');
}
)
);
I keep recieving an error of:
PHP Notice: Trying to get property of non-object.
How can I fix this? I am having a hard time getting a var_dump() of the $created_date and $date variables within the DataTables array to see what the problem is.
For more information about DataTables server-side processing, I am using this template as a base for my DataTables script. The DataTables script also uses this helper class. Thank you in advance!
Just return your string from callback.
'formatter' =>
function ($created_date, $row) use ($current_date) {
$date = new DateTime($created_date);
$diff = date_diff($date, $current_date);
return $diff->format('%d days live'); //That will solve your problem
}
I am working on a feature that checks if external events collide with internal events (in a calendar app). The process looks like this:
My application creates an array of possible events (called $internalEvents)
I source external events from calendars such as Google Calendar, iCloud, etc. (called $externalEvents). These are existing events with the type busy.
Now I have to check if there is any kind of conflict regarding internal and external events. I tried something as you can see below but this is by far not correct or bulletproof.
I tried to reduce it to the minimum as much as possible. This is the data input:
$internalEvents = array(
array(
"start" => "03/29/2016 12:00:00",
"end" => "03/29/2016 13:00:00"
),
array(
"start" => "03/29/2016 12:30:00",
"end" => "03/29/2016 13:30:00"
),
array(
"start" => "03/29/2016 13:00:00",
"end" => "03/29/2016 14:00:00"
),
array(
"start" => "03/29/2016 13:30:00",
"end" => "03/29/2016 14:50:00"
),
array(
"start" => "03/29/2016 14:00:00",
"end" => "03/29/2016 15:00:00"
),
array(
"start" => "03/29/2016 14:30:00",
"end" => "03/29/2016 15:30:00"
),
array(
"start" => "03/29/2016 15:00:00",
"end" => "03/29/2016 16:00:00"
),
array(
"start" => "03/29/2016 15:30:00",
"end" => "03/29/2016 16:30:00"
),
array(
"start" => "03/29/2016 16:00:00",
"end" => "03/29/2016 17:00:00"
)
);
$externalEvents = array(
array(
"start" => "03/29/2016 08:00:00",
"end" => "03/29/2016 12:00:00",
"type" => "busy"
),
array(
"start" => "03/29/2016 15:30:00",
"end" => "03/29/2016 16:00:00",
"type" => "busy"
),
array(
"start" => "03/29/2016 13:30:00",
"end" => "03/29/2016 14:15:00",
"type" => "busy"
)
);
Now I try to find any kind of conflict by comparing the internal event to all external events:
foreach($internalEvents as $internalEvent) {
$internalEventStart = new DateTime($internalEvent['start']);
$internalEventEnd = new DateTime($internalEvent['end']);
$result = true;
echo "\nverifying " . $internalEventStart->format('Y-m-d H:i') . " - " . $internalEventEnd->format('Y-m-d H:i') . "\n";
foreach($externalEvents as $externalEvent) {
$externalEventStart = new DateTime($externalEvent['start']);
$externalEventEnd = new DateTime($externalEvent['end']);
// check if there are conflicts between internal and external events
if ($internalEventStart >= $externalEventStart && $internalEventStart <= $externalEventEnd) {
$result = false;
echo " problem 1: event is between busy time: " . "\n";
}
if ($internalEventStart >= $externalEventStart && $internalEventStart <= $externalEventEnd && $externalEventEnd <= $internalEventEnd) {
$result = false;
echo " problem 2: event starts during busy time: " . "\n";
}
if ($internalEventStart <= $externalEventStart && $externalEventStart <= $internalEventEnd && $internalEventEnd <= $externalEventEnd) {
$result = false;
echo " problem 3: event stops during busy time: " . "\n";
}
if (($internalEventStart <= $externalEventStart) && ($externalEventStart <= $externalEventEnd) && ($externalEventEnd <= $internalEventEnd)) {
$result = false;
echo " problem 4: event during busy time: " . "\n";
}
if (($internalEventStart <= $internalEventEnd) && ($internalEventEnd <= $externalEventStart) && ($externalEventStart <= $externalEventEnd)) {
$result = false;
echo " problem 5: event during busy time: " . "\n";
}
}
if($result) {
echo " result: OK\n";
} else {
echo " result: NOT OK \n";
}
}
I am looking for an algorithm that can find any possible event overlap conflict. Any hint is highly appreciated.
The running code can be found here (IDEone.com).
When two events collide? See this schema:
----E---- CS/EE CE/ES
--N-- < <
--N-- > >
--C-- < >
--C-- < >
--C-- < >
-----C----- < >
··················································
E = Main Event
N = Not Collide Event
C = Collide Event
CS = Compare Event Start
EE = Main Event End
CE = Compare Event End
ES = Main Event Start
As you can see, there is collision only when the start of event C is before the end of event E and the end of event E is after the start of event C. Knowing this helps to find an efficient and short method to compare events.
About the code, a preliminary note: you convert the dates in ISO 8601 before comparing it multiple times in your code, so why do not create a function for this?
function eventsToDate( $row )
{
$retval = array( 'start' => date_create( $row['start'] )->format('Y-m-d H:i:s'), 'end' => date_create( $row['end'] )->format('Y-m-d H:i:s') );
$retval['print'] = sprintf( '%s-%s', substr( $retval['start'],-8,5 ), substr( $retval['end'],-8,5 ) );
return $retval;
}
This function returns an associative array with 'start' and 'end' in your format. I have added a third key, 'print', to use during debug. Note that in the print I consider only hours:minutes (all the dates in your array sample are from same day), but the comparison is made on complete dates. You can omit this 'print' key or replace it with preferred output format.
You execute two nested foreach, and for each loop recalculate the date format. With your array samples, you call DateTime/DateTime::format 36 times. By creating a temporary array with all converted $externalEvents, we can reduce these calls to 12. So, before starting foreach() loop, we use array_map with above custom function and $externalEvents array to create an array with formatted dates:
$externalDates = array_map( 'eventsToDate', $externalEvents );
Then, we start the main foreach() loop on $internalEvents:
foreach( $internalEvents as $internalEvent )
{
$internalDates = eventsToDate( $internalEvent );
echo $internalDates['print'] . PHP_EOL;
$result = True;
foreach( $externalDates as $externalDate )
{
At this point, we compare dates. As mentioned above, we compare start with end and end with start. To simplify next comparison, we use strcmp, a php function that “returns < 0 if str1 is less than str2, > 0 if str1 is greater than str2, and 0 if they are equal”:
$startCmp = strcmp( $internalDates['start'], $externalDate['end'] );
$endCmp = strcmp( $internalDates['end'], $externalDate['start'] );
Now, the comparison:
if( $startCmp<0 && $endCmp>0 )
{
$result = False;
echo " {$externalDate['print']} COLLIDE\n";
}
else
{
echo " {$externalDate['print']} OK\n";
}
}
And, finally, we can print the result:
echo "Result: " . ( $result ? 'OK' : 'NOT OK') . "\n\n";
}
eval.in demo
Note: with above comparison, with first $internalEvent we obtain following result:
12:00-13:00
08:00-12:00 OK
15:30-16:00 OK
13:30-14:15 OK
Result: OK
Instead, if you want this result:
12:00-13:00
08:00-12:00 COLLIDE
15:30-16:00 OK
13:30-14:15 OK
Result: NOT OK
You have to replace above if condition with this:
if( $startCmp<=0 && $endCmp>=0 )
Above code will work, if you want more details about kind of collision, you can test other combinations of start/end inside if condition.
Alternative: Return Colliding Events
If — instead of printing results — you want catch colliding events, you can replace nested foreach() with array_filter in this way:
$result = array_filter
(
$externalDates,
function( $row ) use( $internalDates )
{
$startCmp = strcmp( $internalDates['start'], $row['end'] );
$endCmp = strcmp( $internalDates['end'], $row['start'] );
return( $startCmp<0 && $endCmp>0 );
}
);
At this point, colliding events are in array $result. Obviously, is the array is empty, there are not collisions.
Read more about strcmp()
Read more about array_map()
Read more about array_filter()
I have a multidimensional array like this:
$array = array(
0 => array(
'name' => 'first element',
'start' => '30/04/2015',
'end' => '30/06/2015'
),
1 => array(
'name' => 'second element',
'start' => '01/07/2015',
'end' => '30/09/2015'
),
2 => array(
'name' => 'fourth element',
'start' => '01/10/2015',
'end' => '15/12/2015'
)
);
I need to select one array subarray (item) based on the today date.
today date must be between start date and end date keys.
In the end I would like to have this:
$selected_subarray = array (
'name' => 'first element',
'start' => '30/04/2015',
'end' => '30/06/2015'
)
I use to check between two dates like this:
function check_if_in_range($start_date, $end_date, $today_date)
{
$start_d = strtotime($start_date);
$end_d = strtotime($end_date);
$today_d = strtotime($today_date);
return (($today_d >= $start_d) && ($today_d <= $end_d));
}
I tryed to follow suggestions from this question How to search by key=>value in a multidimensional array in PHP
but if I'm able to filter for a key = value, I'm not able to do the same using the "check_if_in_range" function.
You do know that 30/06/2015 is invalid date, and strtotime() will return false? See here. Format mm/dd/yyyy is an American month, day and year. So your format is non-standard.
Best way is to convert it to standard format, and then use strtotime()example or just use DateTime::createFromFormat()example.
After you learn how formating and converting dates works, then you can just do simple foreach loop, and break on first found result. Here is a little demo.
Try something like the following
foreach($array as $key => $value) {
if(check_in_range($value['start'], $value['end'], $today_date)) {
$selected_subarray = $value;
}
}
I'm trying to let users post from the front end into a nested ACF repeater field.
I've got the sub fields in the first repeater posting fine. But, I can't quite figure out how to get the nested repeater working properly.
Here's the code I have so far:
$event_field_key = 'field_535e6b9ffe3da';
$events[] = array(
'start-date' => $startDate,
'end-date' => $endDate,
'notes' => $_POST['p'.$p.'-notes'],
'start-end-times' => array(
'start-time' => '09:00', // would be dynamic
'end-time' => '17:00' // would be dynamic
)
);
update_field($event_field_key, $events, $post_id);
I'm not sure if I can just nest another array in there, or if I need to do something else.
[UPDATE]
I've just done this and it does input into the first row:
$event_field_key = 'field_535e6b9ffe3da';
$events[] = array(
'start-date' => $startDate,
'end-date' => $endDate,
'notes' => $_POST['p'.$p.'-notes'],
'start-end-times' => array(
'start-time' => '9:00',
'end-time' => ' 17:00'
)
);
update_field($event_field_key, $events, $post_id);
However, this code puts row 1 values both as 9 and row 2 values as 1.
So it looks like:
Row 1: start time: 9, end time: 9
Row 2: start time: 1, end time: 1
I can't seem to find any documentation on this, but it looks like it's possible, just a case of figuring out the syntax.
The fix was an array of arrays:
$event_field_key = 'field_535e6b9ffe3da';
$events[] = array(
'start-date' => $startDate,
'end-date' => $endDate,
'notes' => $_POST['p'.$p.'-notes'],
'start-end-times' => array(
array(
'start-time' => '09:00',
'end-time' => '17:00'
),
array(
'start-time' => '10:00',
'end-time' => '16:00'
)
)
);
update_field($event_field_key, $events, $post_id);
I got this update script in a for :
if(isset($_POST[$i+1 . '_create_metier'])){
$new_entry = array(
'id_parent' => $current[0]->id,
'work' => $_POST[$i+1 . '_create_metier'],
'days' => $_POST[$i+1 . '_create_daycount'],
'price' => $_POST[$i+1 . '_create_price'],
'cr_date' => date('d-m-Y H:i:s'),
'user' => ''
);
var_dump($new_entry);
if(!$this->db->insert('meta_parent',$new_entry)){
echo 'fail';
$p3 = 0;
}else{
echo 'success';
}
}
The var_dump return a well filled array for my db structure, and 'success' is printed, implying the query worked.
But i don't get any modification in my DB. It's not my first use of codeigniter and i never had such an issue.
Thanks for help
I think the error is in the date format, MySQL accept the date in this format: Y-m-d H:i:s
Try replacing
'cr_date' => date('d-m-Y H:i:s'),
with
'cr_date' => date('Y-m-d H:i:s'),