PHP - invalid argument: foreach - inside Wordpress - php

I am experiencing an issue with a wordpress site that I've not encountered before. Allow me to provide some quick details...
Background:
The site I am working on is for a University Radio Station. The station is setup with 9 2 hour blocks of "Show Time" which is split up between various student shows. These blocks of time start at 8AM and end at 2AM, with 2 hour intervals. So 8AM to 10AM and 10AM to 12PM Noon etc... What we need to do is display the show that is "Now Playing" and the show that comes right after "Playing Next".
That said... I have written the below code and it is confirmed working on a test site... That site is http://khill.mhostiuckproductions.com/siteNowplaying/ The code works exactly as I need it to with no faults.
Now when I switch this over to wordpress I get the following error: Warning: Invalid argument supplied for foreach() in [directory to file and line #]
What I have determined/know with the assistance of a gentleman in chat yesterday:
The above error is occurring because the array $showBlocks in the foreach is empty. I know this by doing a var_dump on that array on the wordpress site in which the var dump outputs NULL. This has something to do with my variables being global (global variables can get nasty from what I understand which makes sense).
Said gentleman provided a possible solution which I was not able to get fully working before I had to call it quits for the day, I'll go over that proposed solution below...
The code:
Now I realize this code is terrible and I need to be using classes, and ultimately a database, my code looks like this right now as I do not have a ton of PHP or SQL experience, and I have a deadline that's quickly approaching. I need to get this knocked out and working so I can move on and finish the rest of the site. I plan to develop this further in the background once the new theme launches, ultimately it will tie into the wordpress CMS as a plugin/widget.
That said... I realize what I am doing is very brute force and I am ok with brute forced solutions. As I've said above, my code works perfectly on a standalone test site, it is only when it is moved into wordpress that it breaks.
I have simplified my code to provide only what is needed for a single day (lots of duplicate stuff for each day of the week, you'll understand as you continue further down).
I have the following variables at the top of my file...
$day = date(D); // Textual representation of day in the format of "Mon, Tue, Wed" etc.
date_default_timezone_set('America/New_York'); // Set the default time zone (EST)
I have the following arrays... The first one establishes my "blocks" of time as per their starting and ending times, the second one brings in variables which store my "outputs". These outputs are in a separate file which is included above the file that has all of the code I am showing here. The second array is suplicated for each day of the week, and the variable names change accordingly.
// $showBlocks Array
$showBlocks = array ( // Define available blocks of show time | starts at 8AM ends at 2AM with 2 hour increments
'a' => array ('00:00:01', '02:00:00'), // MIDNIGHT TO 2AM
'b' => array ('02:00:00', '08:00:00'), // OFF AIR TIME
'c' => array ('08:00:00', '10:00:00'),
'd' => array ('10:00:00', '12:00:00'),
'e' => array ('12:00:00', '14:00:00'), // NOON to 2PM
'f' => array ('14:00:00', '16:00:00'),
'g' => array ('16:00:00', '18:00:00'),
'h' => array ('18:00:00', '20:00:00'),
'i' => array ('20:00:00', '22:00:00'),
'j' => array ('22:00:00', '23:59:59'),
);
$mondayShows = array (
'a' => $sunday12a_2a, // MIDNIGHT TO 2AM
'b' => $offAirTime, // OFF AIR TIME
'c' => $monday8a_10a,
'd' => $monday10a_12,
'e' => $mondayy12_2, // NOON to 2PM
'f' => $monday2_4,
'g' => $monday4_6,
'h' => $monday6_8,
'i' => $monday8_10,
'j' => $monday10_12a,
);
The first function... This just checks what day it is, and echo's the appropriate function for that day which is the next bit of code I'll show you. I echo the nowPlaying() function in my site where I want my output to appear.
function nowPlaying() {
global $day;
if ($day == "Sun") { //IF DAY IS TRUE THEN PERFORM AN ACTION
echo sundayShow();
} else if ($day == "Mon") {
echo mondayShow();
} else if ($day == "Tue") {
echo tuesdayShow();
} else if ($day == "Wed") {
echo wednesdayShow();
} else if ($day == "Thu") {
echo thursdayShow();
} else if ($day == "Fri") {
echo fridayShow();
} else if ($day == "Sat") {
echo saturdayShow();
}
}
For the sake of simplicity I am going to show you only one of the functions that appear inside the above function, we'll use Monday since it's Monday.
This function uses the two arrays seen above as inputs, the $mondayShows array variable changes to $tuesdayShows for the tuesdayShow() function. (basically exactly the same code with different variable name for the array input) The foreach here is the line where the error code says there is a problem. Again, as someone from the php chat guided me to, is because when I put this code into wordpress, suddenly my array becomes empty.
function mondayShow() {
global $mondayShows, $showBlocks; // GLOBALIZE THESE VARIABLES
foreach ($showBlocks as $name => $range) {
if (time() > strtotime($range[0]) && strtotime($range[1]) > time()) { // checks if time() is between defined ranges from $showBlocks array
echo($mondayShows[$name]);
}
}
}
Earlier I mentioned also displaying what is "Playing Next". This is handled by duplicating all of the above code with new names, for example the name of the equivalent code for the above function becomes mondayNextShow(). To make the code display the actual next show I add 7200 (number of seconds in 2 hours) to time() so... time + 7200. This addition is inside the if statement of the above code... so it now looks like this...
if (time() + 7200 > strtotime($range[0]) && strtotime($range[1]) > time() + 7200) {
What was suggested to me in chat but I was unable to get working:
In chat, it was suggested I get rid of the global variables, and include my array directly into the function via a separate file... I tried this by moving the above $showBlocks array to a separate file "now-playing-array.php" for instance. The array code was changed from the above to instead return the array so it now looks like this:
return array (
'a' => array ('00:00:01', '02:00:00'), // 12AM MIDNIGHT TO 2AM
'b' => array ('02:00:00', '08:00:00'), // OFF AIR TIME
'c' => array ('08:00:00', '10:00:00'),
....................
);
I then remove $showBlocks from global variables of the above function, and I include said file into the function using the __DIR__ magic constant.
The above function now looks like this:
function mondayShow() {
global $mondayShows; // GLOBALIZE THESE VARIABLES
$showBlocks = include __DIR__."/now-playing-arrays.php";
foreach ($showBlocks as $name => $range) {
if (time() > strtotime($range[0]) && strtotime($range[1]) > time()) { // checks if time() is between defined ranges from $showBlocks array
echo($mondayShows[$name]);
}
}
}
A var_dump on $showBlocks now produced: bool(false)
Now the questions...
Please keep in mind this code is very brute forced and I know and realize that, but that's what I want for now. I am going to be using this project to expand my PHP into using classes and databases and such but I don't have the time for that now. I am not looking for, your code is terrible you should just start over and do it the right way answers... I know that already.
First, if you understand the route this gentleman from chat was trying to take me, is it the best route to take?
If it is the best route to take then, how do I go about finishing it off? From what I gather the bool(false) thing means it can't find my file? The files are all in the same folder.

You could put your return arrays into functions, and then simply call the function and assign it to a variable from within your mondayShow() function:
function showBlocks(){
return array (
'a' => array ('00:00:01', '02:00:00'), // MIDNIGHT TO 2AM
'b' => array ('02:00:00', '08:00:00'), // OFF AIR TIME
'c' => array ('08:00:00', '10:00:00'),
'd' => array ('10:00:00', '12:00:00'),
'e' => array ('12:00:00', '14:00:00'), // NOON to 2PM
'f' => array ('14:00:00', '16:00:00'),
'g' => array ('16:00:00', '18:00:00'),
'h' => array ('18:00:00', '20:00:00'),
'i' => array ('20:00:00', '22:00:00'),
'j' => array ('22:00:00', '23:59:59'),
);
}
function mondayShows(){
return array (
'a' => "a", // MIDNIGHT TO 2AM
'b' => "b", // OFF AIR TIME
'c' => "c",
'd' => "d",
'e' => "e", // NOON to 2PM
'f' => "f",
'g' => "g",
'h' => "h",
'i' => "i",
'j' => "j",
);
}
function mondayShow() {
$showBlocks = showBlocks();
$mondayShows = mondayShows();
foreach ($showBlocks as $name => $range) {
if (time() > strtotime($range[0]) && strtotime($range[1]) > time()) {
echo($mondayShows[$name]);
}
}
}
mondayShow();
This way, you don't need to explicitly globalize anything, and you don't need to worry about having extra files. Simply make a function for each show listing array, and have it return.
One small thing: In the code above, I changed the $mondayShows array values to something that was defined (just letters), so make sure you're actually assigning those to something.

Related

How to write to new file once certain line is reached in php

I am trying to write a php script that will process each line of an m3u file and write it to the corresponding hour file. Whenever the process begins we always start at hour 00 or 12am midnight. Everything from the first line until the line that says END-OF-HOUR goes into file $month$day-$hour.58.15.m3u
$month and $day are to stay constant during this entire process and do successfully. Where I run into my problem is when I hit the END-OF-HOUR line. What is suppose to happen is that the script switches $hour from 00 to 01. The preceding 0 is very important for hours 0-9. Once the switch occurs it will start writing from the next line in the file to the hour 01 file until it hits the END-OF-HOUR line again. Once again increasing in hour value.
This needs to continue for all 24 hours of the day.
What is happening is that this script is copying the master file all into the hour 00 file.
Here is what I was able to do on my own:
<?php
//$location="";
$file="PLAYLIST";
$month="Nov";
$day="28";
$hour="00";
$outputlocation="Processed";
$outputfile="$month$day-$hour.58.15";
//Create Playlist Files Code Here and Working//
$handle = fopen("$file.m3u", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
//Begin Processing
//If End Of Hour
if ($line=="END-OF-HOUR"){
//If Not 11PM
if ($hour !=="23"){
$hour="$hour" + 1;
}
//If 11PM
if ($hour =="24"){
echo "<script>alert('MusicMaster File Processing Complete')</script>";
}
}
//If Not End Of Hour
if ($line !="END-OF-HOUR"){
$ofile=file_get_contents("$outputlocation\\$outputfile.m3u");
$nfile="$ofile
$line";
file_put_contents("$outputlocation\\$outputfile.m3u", "$nfile");
}
}
fclose($handle);
} else {
// error opening the file.
echo "<script>alert('Error Opening MusicMaster File')</script>";
}
//https://stackoverflow.com/questions/13246597/how-to-read-a-file-line-by-line-in-php
?>
I'm not well versed in looping in php. just very basic if statements and mysql queries.
This is the file it pulls from and outputs to each hour. This is only a snippet:
M:\JINGLES\TOH\LEGAL ID 20170416-A.mp3
M:\ITUNES\Music\Danny Gokey\Rise (Album)\02 If You Ain't In It.mp3
M:\ITUNES\Music\MercyMe\MercyMe, It's Christmas\06 Have a Holly Jolly Christmas.mp3
M:\JINGLES\STANDARD\Stay Tuned.mp3
M:\ITUNES\Music\Royal Tailor\Royal Tailor\06 Ready Set Go.mp3
M:\ITUNES\Music\Third Day\Revelation\03 Call My Name.mp3
M:\THE STORY BEHIND IT\Mandisa - Bleed The Same (Song Story).mp3
M:\PROMOTIONS\Valley Park Flea Market & Resale (6PM 5-29).mp3
M:\PROMOTIONS\FoundationLyrics_com.mp3
M:\PROMOTIONS\VinVlogger_com (5-15-17).mp3
END-OF-HOUR
M:\JINGLES\TOH\LEGAL ID 20170816.mp3
M:\ITUNES\Music\Audio Adrenaline\Kings & Queens\02 Kings & Queens.mp3
M:\ITUNES\Music\Stars Go Dim\Stars Go Dim\01 Doxology.mp3
M:\JINGLES\STANDARD\LIN\LIN-002.mp3
M:\ITUNES\Music\NewSong\Newsong\Christian.mp3
M:\ITUNES\Music\David Dunn\Crystal Clear - EP\02 Have Everything.m4a
M:\THE STORY BEHIND IT\Mandisa - Bleed The Same (Song Story).mp3
M:\PROMOTIONS\Valley Park Flea Market & Resale (6PM 5-29).mp3
END-OF-HOUR
I know I'm doing something wrong and just can't seem to figure out what it is. Any help you can provide would be very much appreciated.
I would start by changing this.
$outputfile="$month$day-$hour.58.15";
This needs to be updated while the while loop is iterating ( or at least when you change the hour )
Right now you are just using the initial value you set for hour 00 the entire time.
This is why you get the behaviour you have of it not changing the hour, because it's value is never re-assigned as the loop runs.
UPDATE
I took the liberty to rewrite your code. Sorry I'm a perfectionist, the more I looked at the more I didn't like it. ( not tested, as I don't have any files )
$file="PLAYLIST";
//Use an array, it's more concise and readable
$date =[
'month' => "Nov",
'day' => 28,
'hour' => 0,
'minute' => 58, //added for extendability
'second' => 15 //added for extendability
];
$outputlocation="Processed";
/*** Create Playlist Files Code Here and Working ***/
//open file. We can't proceed without the file, might as well stop here if we can't open it.
if(false === ($handle = fopen("$file.m3u", "r"))) die("Failed to open file.");
//while each line in the file
while (($line = fgets($handle)) !== false) {
if(trim(strtoupper($line)) =="END-OF-HOUR"){//If $line = End Of Hour
//trim removes whitespace from front and back, strtoupper should be self explanitory
if($hour < 24 ){
//if less the 12pm (and $line = 'END-OF-HOUR' )
//increment hour and left pad.
//you may need to use < 23 your logic forgot about it.
++$date['hour'];
}else{
//else if 12pm (and $line = 'END-OF-HOUR' )
echo "<script>alert('MusicMaster File Processing Complete')</script>";
}
continue;
/*
goes to next line ( iteration of the loop )
none of the code below this runs.
logically this is essentially what you had ^
so there is no need to continue
*/
}
// 0 pad left any parts that are len of 1 lenght
$fixed = array_map(function($i){
return (strlen($i) == 1) ? "0$i":$i;
}, $date);
/*
create the filename just before we use it
not that it matter in PHP, but the original array stays as INT's
the month is strlen() = 3, so it's unchanged by the above.
*/
$outputfile = $fixed['month'].$fixed['day'].'-'.$fixed['hour'].'.'.$fixed['minute'].'.'.$fixed['second'];
//this is all you..
$ofile=file_get_contents("$outputlocation\\$outputfile.m3u");
$nfile="$ofile
$line";
file_put_contents("$outputlocation\\$outputfile.m3u", "$nfile");
} //end while
I tested a few things with this:
$date =[
'month' => "Nov",
'day' => 28,
'hour' => 0,
'minute' => 58, //added for extendability
'second' => 15 //added for extendability
];
$fixed = array_map(function($i){
return (strlen($i) == 1) ? "0$i":$i;
}, $date);
$outputfile = $fixed['month'].$fixed['day'].'-'.$fixed['hour'].'.'.$fixed['minute'].'.'.$fixed['second'];
print_r($fixed);
echo "\n$outputfile\n";
Outputs
Array
(
[month] => Nov
[day] => 28
[hour] => 00
[minute] => 58
[second] => 15
)
Nov28-00.58.15
You can try it in this sandbox
UPDATE
If you wan't to trim all the lines, then just separate this
while (($line = fgets($handle)) !== false) {
if(trim(strtoupper($line)) =="END-OF-HOUR"){//If $line = End Of Hour
Like this
while (($line = fgets($handle)) !== false) {
$line = trim($line);
if(strtoupper($line) =="END-OF-HOUR"){//If $line = End Of Hour
A few other things about trim,
you can set the character that it trims, by setting the second argument, like this trim('**foo**', '*'); //outputs 'foo'
you can set more then one character but it acts like OR and replaces each one regardless the order such as trim('abcFOOcba', 'abc'); //outputs 'FOO'
you can trim just the right with rtrim(' Foo '); //outputs ' Foo' or trim just the left with ltrim(' Foo '); //outputs 'Foo '
I don't know why they have 3 separate functions, i'd prefer this trim($string, $match, $flag); where flag is TRIM_RIGH, TRIM_LEFT, TRIM_BOTH but, I guess you can't get everything you want. ( like the MySql version )
You can trim an array for white space pretty easily, by using array_map
$a = [ 'Foo ', ' Bar '];
$a = array_map('trim', $a);
print_r($a); //outputs ['Foo', 'Bar']
Documentation for PHP Trim
MySQL also as a TRIM() function SELECT TRIM(BOTH ' ' FROM column) AS foo They are very useful.
Documentation for Mysql Trim

Create new elements in an array based on existing values

I have the following array which contains a set of periods:
Array
(
Array
(
[period_start] => 1
[period_end] => 12
)
Array
(
[period_start] => 4
[period_end] => 8
)
)
I want to split the periods that overlap other periods. For example, because the second period is overlapping the first, it should split the first period into two periods so that it looks something like this:
Array
(
Array
(
[period_start] => 1
[period_end] => 3
)
Array
(
[period_start] => 4
[period_end] => 8
)
Array
(
[period_start] => 9
[period_end] => 12
)
)
So that no two periods contain a start and end value within the range of another period. But I have no idea how best to achieve this in an efficient manner. Any help would be appreciated.
EDIT: To the comments, this post was more a plea for rubber ducking, not for getting someone else to do my work for me. I've got a solution to my problem (brace yourselves):
// Sort the collection by period_start in ascending order.
function sortByPeriod(&$collection) {
usort($collection, function ($value1, $value2) {
if (!array_key_exists('period_start', $value1) || !array_key_exists('period_start', $value2)) {
return 0;
}
if ($value1['period_start'] == $value2['period_start']) {
return 0;
}
return $value1['period_start'] < $value2['period_start'] ? -1 : 1;
});
}
$periods = array();
$products = array(
array(
'period_start' => 4,
'period_end' => 8
),
array(
'period_start' => 1,
'period_end' => 12
)
);
sortByPeriod($products);
foreach ($products as $product) {
// Store them in $periods using a key, so that if an identical period comes along on a future iteration, it doesn't get counted. The keys aren't required.
if (array_key_exists('period_start', $product) && !is_null($product['period_start'])) {
if (!array_key_exists($product['period_start'] . '-' . $product['period_end'], $periods)) {
$productStart = $product['period_start'];
$productEnd = $product['period_end'];
// Go through each period already inserted
foreach ($periods as &$period) {
$periodStart = $period['period_start'];
$periodEnd = $period['period_end'];
If the product's start overlaps the period's end
if ($productStart <= $periodEnd) {
// Set that period's end to the product's start - 1
$period['period_end'] = $productStart - 1;
// If the overlapping product is entirely within the period (e.g. period is 1-12, product is 4-8, like the example provided earlier)
if ($productEnd <= $periodEnd) {
// Add a new period, whose start is the product's end + 1 and the end is the initial period's end.
$periods[($productEnd + 1) . '-' . $periodEnd] = array(
'period_start' => $productEnd + 1,
'period_end' => $periodEnd
);
// The product's period isn't entirely within the period (e.g. period is 1-6, product is 4-8)
} else {
// Add a new period from product start to period end (e.g. following the example above, the period becomes 1-3, insert 4-6)
$periods[$productStart . '-' . $periodEnd] = array(
'period_start' => $productStart,
'period_end' => $periodEnd
);
// Set the product's start to the period's end + 1 (e.g. 7)
$productStart = $periodEnd + 1;
}
}
}
// Add the period (following the example iteration above, product start = 7, end = 8)
$periods[$productStart . '-' . $productEnd] = array(
'period_start' => $productStart,
'period_end' => $productEnd
);
}
}
// After one iteration, we have 1-3, 4-6 and 7-8
}
sortByPeriod($periods);
$periods = array_values($periods);
print_r($periods);
Which works and yields the expected output as shown above. However, as you can see, it isn't very well organised and I feel as if there would be a better way to approach this.
Thank you.
I realised that I was going about this in a bit of a strange way. My thinking was that if I had a period range (let's say 1-8) and another (4-12), it should split these ranges up and leave it with 1-3, 4-8, 9-12. While the output is indeed the output that I desire, getting to it by splitting it up and adding new periods to compensate for the missing ranges in between was too complicated. I was thinking of it like this (and I had it working this way):
I have three loaves of bread, each a different size. I need to split them all up so that I have several slices of the loaf, enough to equal the content of the largest loaf. Okay, let's take a piece out of this loaf, a piece out of that loaf, and put it all together.
It's all a mess. Really, the best way to go about it is to use the largest loaf and cut in the exact places that the other loaves would fit, so instead of using three loaves, i'm just using one.
I put the theory into practice (using JavaScript. I can port it to PHP). First I need a way for each period to be indistinguishable, so that if my initial periods are something along the lines of 1-3, 1-12 and 4-8, it will count the 1-3 and 4-8 as two separate periods. Luckily, all of my items are products that have a normal price and a discounted price. The discounted price takes effect during the discount period.
Next, I need to identify the largest period and note it's start and end:
var range = {};
this.products.forEach(product => {
if (!range.start) {
range.start = product.start;
}
if (!range.end) {
range.end = product.end;
}
if (product.start < range.start) {
range.start = product.start
}
if (product.end > range.end) {
range.end = product.end;
}
});
Now, for each product, I iterate from start to end by 1 each iteration, storing the product's discount price if it's period is within the current iteration, or otherwise it's normal price:
var periodCounter = [];
this.products.forEach(product => {
for (i = range.start; i <= range.end; i ++) {
if (!periodCounter[i]) {
periodCounter[i] = 0;
}
if (i >= product.start && i <= product.end) {
periodCounter[i] += product.def_amount;
} else {
periodCounter[i] += product.amount;
}
}
});
Great. Now I have an array filled with prices for all products during each single one month period. Now I need to identify the actual periods. This is really easy - iterate through the array, check to see if the current price is equal to the previous price. If it is, we're still in a period. If it isn't, we've reached the end of that period and started a new one:
var periods = [];
var periodStart = 0;
var periodEnd = 0;
for (i = range.start; i <= range.end; i ++) {
if (i == range.start) {
periodStart = i;
} else {
if (periodCounter[i] != periodCounter[i-1]) {
periodEnd = i-1;
periods.push({
start: periodStart,
end: periodEnd,
amount: periodCounter[i-1]
});
periodStart = i;
}
if (i == range.end) {
periods.push({
start: periodStart,
end: i,
amount: periodCounter[i]
});
}
}
}
If by any chance the totals of two "logical" periods equal the same price, it doesn't really matter. The end user just needs to know what the price is for these periods, they gain no information in knowing that two periods equal the same price, so in essence, you might as well just concatenate those periods into one large period, which is what would happen. If it's absolutely necessary to display the true "logical" periods, instead of storing the price in the counter, use a byte value (1, 2, 4, 8, etc).
I made a codepen for this project, using Vue.js and Bulma to display the products and the correct periods. Of course, I'm open to better ways that I might be able to go about this.

PHP compare $_POST array members

I have a form where users have to enter timecodes or time values 00:00:00, which at the end must fulfill the condition that each timestamp must be larger than the previous. I know it can be achieved by processing the $_POST['timecode']. However can't make it work. This is what I've been working around. Sorry for my ignorance, but being sure this is the way and not getting the result drove me to ask here.
$q_tc=count($_POST['timecode']);
for ($w = 0; $w < $q_tc; $w++) {
if ($_POST['id_ts'][$w] > $_POST['id_ts'][$w+1]) {
echo "error: should be smaller than next timecode";
} else {
// ...
}
}
What I get after running this code is that everytime an error message is deployed, even without the condition being placed.
I'm running PHP 5.4 on a apache server. This is what the $_POST['timecode'] contains:
Array ( [0] => 00:00:30 [1] => 10:00:00 [2] => 12:00:00 )
And as it can be seen, no error should be generated, but the code does not check accurately the requested condition.
You end up comparing the last one to a null value, because you look at 0 and 1, then 1 and 2, then 2 and 3, but key 3 doesn't exist.
Try this fix. Skip the first one, compare each to the previous.
$arr = array('00:00:30', '10:00:00', '12:00:00');
$q_tc=count($arr);
for ($w = 1; $w < $q_tc; $w++) {
if ($arr[$w-1] > $arr[$w]) {
echo "error: should be smaller than next timecode";
}
}

Creating hour statistics using arrays and memcached

I am trying to count how many hits I have on my site each hour, but am not sure how to approach this.
Here is what i have now:
if($cacheAvailable == true){ // WE GOT A CACHE
date_default_timezone_set("UTC");
$thisHour = date("H", time());
$moveStats = $memcache->get('moveStats');
if(!$moveStats){
$todayStats = array(array(hour => $thisHour, hits => 1, executetime => $total_time));
$memcache->set('moveStats', $todayStats);
}
foreach ($moveStats as $k => $v) {
if($v['hour'] == $thisHour){
$moveStats[$k]['hits']=$moveStats[$k]['hits']+1;
}
}
$memcache->set('moveStats', $moveStats);
echo '<pre>';
print_r($moveStats);
echo '</pre>';
}
This makes an array like this:
Array
(
[0] => Array
(
[hour] => 18
[hits] => 6
[executetime] => 0
)
)
//##### EDIT ######//
I am able to add to the current hour but I don't know how to add a new hour when the clock turns into the new hour?
Hoping for help and thanks in advance.
You just have to check if that index already exists, if not create a new one, and always increase the old value:
$todayStats = $moveStats;
if (!isset($todayStats [$thisHour])) {
$todayStats[$thisHour] = 0;
}
$todayStats[$thisHour]['hits']++;
$todayStats[$thisHour]['executetime'] = $total_time;
But you have some other problems in your implementation:
- Don't use string without quotes. That will try to call a constant with that name and only as fallback return the string itself. It also raises a notice.
- $thisHour won't contain the current hour. If you really want to have the hour try: date('H') only.

How to put information dynamically on tables using jQuery based on certain criteria?

Let's imagine that I have to make a table with the following structure with PHP. Every cell identified with NamedayHour
is just an indicator ( Mon0, Mon1, and so on for every day ). I should put information on that cells, that is different for every day and hour.
The whole structure is something like this :
<table border="1" >
<th>Hour</th>
<th>Mon 25-06-2012</th>
<th>Tue 26-06-2012</th>
<th>Wed 27-06-2012</th>
<th>Thu 28-06-2012</th>
<th>Fri 29-06-2012</th>
<tr><td>8:00</td><td>Mon0</td><td>Tue0</td><td>Wed0</td><td>Thu0</td><td>Fri0</tr>
<tr><td>8:20</td><td>Mon1</td><td>Tue1</td><td>Wed1</td><td>Thu1</td><td>Fri1</tr>
<tr><td>8:40</td><td>Mon2</td><td>Tue2</td><td>Wed2</td><td>Thu2</td><td>Fri2</tr>
<tr><td>9:00</td><td>Mon3</td><td>Tue3</td><td>Wed3</td><td>Thu3</td><td>Fri3</tr>
<tr><td>9:20</td><td>Mon4</td><td>Tue4</td><td>Wed4</td><td>Thu4</td><td>Fri4</tr>
<tr><td>9:40</td><td>Mon5</td><td>Tue5</td><td>Wed5</td><td>Thu5</td><td>Fri5</tr>
</table>
So, I have the arrays:
$hoursMonday = array("8:00", "8:20", "8:40")
$hoursMondayAssigned = array("8:00", "8:20")
$hoursMondayAvailable = array("8:40")
I have these 3 arrays for every day from Monday to Friday.
Then I need to write the hours in the table for every day. For example, in this case, I need to put on the cell for Monday and hour: 8:40 the text
"Available", and for "8:00" and "8:20" I should put on the column Monday for these hours, the system should put "Busy" for both of them.
The resulting table, using the arrays of the example, should be like the following table:
<table border="1" >
<th>Hour</th>
<th>Mon 25-06-2012</th>
<th>Tue 26-06-2012</th>
<th>Wed 27-06-2012</th>
<th>Thu 28-06-2012</th>
<th>Fri 29-06-2012</th>
<tr><td>8:00</td><td>BUSY</td><td>Tue0</td><td>Wed0</td><td>Thu0</td><td>Fri0</tr>
<tr><td>8:20</td><td>BUSY</td><td>Tue1</td><td>Wed1</td><td>Thu1</td><td>Fri1</tr>
<tr><td>8:40</td><td>AVAILABLE</td><td>Tue2</td><td>Wed2</td><td>Thu2</td><td>Fri2</tr>
<tr><td>9:00</td><td>Mon3</td><td>Tue3</td><td>Wed3</td><td>Thu3</td><td>Fri3</tr>
<tr><td>9:20</td><td>Mon4</td><td>Tue4</td><td>Wed4</td><td>Thu4</td><td>Fri4</tr>
<tr><td>9:40</td><td>Mon5</td><td>Tue5</td><td>Wed5</td><td>Thu5</td><td>Fri5</tr>
</table>
</html>
I would like to use jQuery, or just PHP to solve this.
One of the things to note, is that the parameter of frequency ( in this case 10 minutes ) might vary. If the frequency is set to 30 minutes, for example,
the times will be: 8:00 , 8:30, 9:00, 9:30 and so on.
I don't really know how to solve this using jQuery. I know how to write the table using a for loop, but complexity is leveling up when I need to
put the information on the correct cell depending of the day and hour.
Thanks.
You could do the following in PHP to find out for each hour if it's assigned already or free:
$hoursMonday = array("8:00", "8:20", "8:40");
$hoursMondayAssigned = array("8:00", "8:20");
$hoursMondayAvailable = array("8:40");
foreach( $hoursMonday AS $hour ) {
if( in_array( $hour, $hoursMondayAssigned ) ) {
echo 'Busy at ' . $hour;
} else if ( in_array( $hour, $hoursMondayAvailable ) ) {
echo 'Free at ' . $hour;
}
}
To automate looping through all the days I would suggest using a recursive array for each day, for example:
$monday = array(
'free' => array(
'08:40', '09:00'
),
'busy' => array(
'08:40',
),
'free' => array(
'09:00',
),
);

Categories