Do not repeat string more than once - php

In the database I have various dates stored like so:
ID| Dates
-----------------
1 | 23 April 2014
2 | 24 April 2014
3 | 25 April 2014
4 | 01 May 2014
5 | 02 May 2014
I managed to trim all the digits from the string with PHP which only leaves me with the month titles.
What I am trying to accomplish is to loop the months with a While loop and only show each month only once.
I want to achieve the following:
<h1>April<h1>
<p>23 April 2014</p>
<p>24 April 2014</p>
<p>25 April 2014</p>
<h1>May</h1>
<p>01 May 2014</p>
<p>02 May 2014</p>
So, what I actually want is to dynamically sort the months under its rightful tag
I hope somebody can help
Thank you

If your are query ascending by date, you can achieve your requirement by following example:
<?php
$results = array();// your dataset
$month_name = array(); // empty array
foreach($results as $row){
$this_month = date('M', strtotime($row['date_field']));
if (!in_array($this_month, $month_name)) {
$month_name[] = $this_month;
echo "<h1>{$this_month}</h1>";
}
echo "<p>{$row['date_field']}</p>";
}
I believe there are more better solution can be possible (by change database data field as date instead of keep date as string), but from your current scenario, this solution I think perfect.
******EDIT******
Updated code base on your provided example:
$month_name = array();
$result = mysql_query($sql);
while ($record = mysql_fetch_assoc($result)) {
// $record['date_field'] is your dates field of your database
$this_month = date('M', strtotime($record['date_field']));
if (!in_array($this_month, $month_name)) {
$month_name[] = $this_month;
echo "<h1>{$this_month}</h1>";
}
echo "<li> <a href='dates.php?ID=" . $record['ID'] . "'>";
echo "<p><strong>" . $record['date'] . " | " . $record['timeStart'] . " - " . $record['timeEnd'] . "</strong></p>";
echo "<p>" . $record['place'] . " - " . $record['provincie'] . "</p>";
echo "<p>" . $record['kind'] . "</p>";
echo "</a> </li>";
}

Related

Minus two numbers in a foreach loop and display result for each result

I have a foreach loop as below.
I'm looking to minus the $wrap->wrap_total from the one that came before it in the loop and struggling!
foreach ($wrap_query->result() as $wrap)
{
echo date("D d M Y", strtotime($wrap->wrap_date))." - ";
echo money_format('%n', $wrap->wrap_total)." - ";
echo "<br />";
}
Current output is as below:
Sun 07 Aug 2016 - £10,000.00
Sat 06 Aug 2016 - £12,000.00
Fri 05 Aug 2016 - £8,000.00
What I'd like is:
Sun 07 Aug 2016 - £10,000.00 (-£2,000)
Sat 06 Aug 2016 - £12,000.00 (£4,000)
Fri 05 Aug 2016 - £8,000.00
Any and all help appreciated!
The Commented code below might get you started. The Demo can be found here as well.
<?php
setlocale(LC_MONETARY, 'en_GB');
// LET US IMAGINE FOR A MOMENT THAT $wrap_query->result() CONTAINS
// THE FOLLOWING SIMULATED DATA MIMICKING YOUR DATA STRUCTURE...
$simulatedWrap1 = new stdClass();
$simulatedWrap2 = new stdClass();
$simulatedWrap3 = new stdClass();
$simulatedWrap1->wrap_date = "2016-08-07";
$simulatedWrap1->wrap_total = 10000.00;
$simulatedWrap2->wrap_date = "2016-08-06";
$simulatedWrap2->wrap_total = 12000.00;
$simulatedWrap3->wrap_date = "2016-08-05";
$simulatedWrap3->wrap_total = 8000.00;
$rWrapCollection = [
$simulatedWrap1,
$simulatedWrap2,
$simulatedWrap3,
];
// MAKE A COPY OF THE MAIN ARRAY COLLECTION
// THIS WOULD BE USED WITHIN THE LOOP TO MOVE THE ARRAY CURSOR
// TO THE NEXT ELEMENT WITHIN THE COLLECTION
$rWrapClone = $rWrapCollection;
// JUST FOR FUN: EXPLICITLY MOVE THE CURSOR TO THE FIRST
// ELEMENT IN THE COLLECTION
current($rWrapClone);
// CREATE AND INITIALIZE A VARIABLE $output TO AN EMPTY STRING.
// THIS VARIABLE WILL HOLD THE HTML CONTENT GENERATED WITHIN THE LOOP
$output = "";
foreach ($rWrapCollection as $index=>$wrap){
// MOVE THE CURSOR TO THE NEXT ITEM & CATCH THE VALUE IN A VARIABLE
$nextWrap = next($rWrapClone);
$output .= date("D d M Y", strtotime($wrap->wrap_date)) . " - ";
$output .= money_format('%n', $wrap->wrap_total);
// IF THERE IS STILL ANY NEXT ITEM, THEN CALCULATE
// THE DIFFERENCE BETWEEN THE CURRENT & NEXT ITEM
if($nextWrap){
$difference = $wrap->wrap_total - $nextWrap->wrap_total;
$output .= " (" . money_format('%n',$difference) . ")";
}
$output .= "<br />";
}
echo $output;
//PRODUCES:
Sun 07 Aug 2016 - £10,000.00 (-£2,000.00)
Sat 06 Aug 2016 - £12,000.00 (£4,000.00)
Fri 05 Aug 2016 - £8,000.00
Effective Code as it relates to your unique case:
<?php
$output = "";
$resultsCopy = $wrap_query->result();
current($resultsCopy);
foreach ($wrap_query->result() as $wrap) {
$nexWrap = next($resultsCopy);
$output .= date("D d M Y", strtotime($wrap->wrap_date)) . " - ";
$output .= money_format('%n', $wrap->wrap_total);
if($nexWrap){
$difference = $wrap->wrap_total - $nexWrap->wrap_total;
$output .= " (" . money_format('%n',$difference) . ")";
}
$output .= "<br />";
}
echo $output;
Keep track of the previous item as you go. If there is a previous item (all results after the first one) calculate the difference and output it before starting the new line.
$previous = null;
foreach ($wrap_query->result() as $wrap) {
if ($previous) {
echo " (" .money_format('%n', $previous->wrap_total - $wrap->wrap_total) .")<br>";
}
echo date("D d M Y", strtotime($wrap->wrap_date))." - ";
echo money_format('%n', $wrap->wrap_total);
$previous = $wrap; // set previous to current
}

PHP & HTML Creating a table issue

I am creating a table for a schedule and I am having trouble formatting it correctly. Here is what my output table looks like
Users| Action | Monday | Monday | Monday | Wednesday
09/23/13 09/23/13 09/23/13 09/25/13
11:00 AM 1:00 PM 2:00 PM 10:00 AM
----- -------- ---------- --------- ----------- -----------
Jack
John
Tim
I want my output to look like this:
Users| Action | Monday | Monday | Monday | Wednesday
09/23/13 09/23/13 09/23/13 09/25/13
11:00 AM 1:00 PM 2:00 PM 10:00 AM
----- -------- ---------- ----------- ------------- ---------
Jack
John * * *
Tim *
new
This is reading data from two text files, one for the schedule that looks like this:
2013-09-23^11:00|13:00|14:00
Where it is visualized to look like this with an index for the users file
0 1 2
2013-09-23^11:00|13:00|14:00
Where each number maps to a user
eg user file
Jack
John^0|1|3
Tim^2
John's 0 maps to the first date of the schedule file and marks it..
heres my code do you have any idea of how to fix it? i need to first put blank rows in per user based on the columns that the schedule file reads in...
<!DOCTYPE html>
<html>
<head>
<title>Scheduler</title>
</head>
<body>
<h2>
<form action = "update.php" method = "POST" >
<center>Select Your Meeting Times</center></h2>
<?php
echo "<table border= '1'
cellpadding='10'>
<tr>
<th>User</th>
<th>Action</th>";
date_default_timezone_set('America/New_York');
//error_reporting(1);
getTimes();
displaySchedule();
function displaySchedule()
{
// used for displaying schedule times
$text = "user.txt"; // open up the user file.
$f = fopen($text, "r+");
if (file_exists("user.txt"))
{
while($line = fgets($f,1000))
{
$name = getUsers($text, $line);
echo "<tr>" . "<td>" . $name . "</td>" . "</tr>\n";
}
}else{
#create the file method.
}
echo "<tr>" . "</tr>";
}
#this method gets the users from the text file and diplays them.
function getUsers(&$text1, &$line)
{
list($name, $num) = explode('^', $line);
$num1 = explode('|', $num); // num 1 now holds the number where the time entry mark goes
// setTimes($name, $num1) // sets the times for the user.
return $name;
}
#When the user is either new or active, set the times
function setTimes(&$name, &$num1)
{
}
function getTimes()
{
$file = file("schedule.txt"); // open up the schedule file
// loop through the schedule file
foreach($file as $s){
# s = string like '2013-04-11^12:00|4:00|14:00'
list($year, $rest) = explode("^", $s);
$rest_arr = explode("|", $rest); // time = 12:00 etc..
list($year, $month, $day) = explode('-', $year); // this cuts them down.
$year= intval($year, 10);
$month= intval($month, 10);
$day= intval($day, 10); $h = mktime(0, 0, 0, $month, $day,$year);
$d = date("F dS, Y", $h); //used to get the day of the week
$w= date("l", $h); // w now holds the day of the week.
// while through the schedule file, loop through each of times and displays them.
foreach($rest_arr as $time){
//$convert = (string)$rest_arr;
//$convertedTime = date("g:ia", strtotime($convert));
echo "<th>" . $w . "<br>" . $month . "/" . $day . "/" . $year . "<br>" . $time . "</th>\n";
// sets the header
} // end this
} // end 1st foreach for file.
}
function createFile()
{
}
function drawTable()
{
$rows = 10; // define number of rows
$cols = 4;// define number of columns
echo "<table border='1'>";
for($tr=1;$tr<=$rows;$tr++){
echo "<tr>";
for($td=1;$td<=$cols;$td++){
echo "<td>row: ".$tr." column: ".$td."</td>";
}
echo "</tr>";
}
echo "</table>";
}
echo "<th><br></th>
<tr>
<th>Total</th>
</tr>
</table>";
?>
</body>
</html>

Finding Distinct Month

I make a page, that display records from database,in group of 10 records per page using paginition concept,
i wanna print Like: Month name/Year.
That month and year is distinct form that page means of 10 records.
Suppose page number 10 contains 10 records with 3 distinct month named Dec 2011 , Jan 2012 and, March 2012,
In this case i want to print Month: Dec/2011 ,Jan,March/2012
Thanks in advance..
If your date is stored like you write it: Dec 2011, Jan 2012 then you should do like this
$arr = array();
$sql = mysql_query(__YOUR_SQL__);
while($row = mysql_fetch_array($sql)) {
$date = explode(" ", $row['date']);
if(!array_key_exists($date[1], $arr))
$arr[$date[1]] = array();
array_push($arr[$date[1]], $date[0]);
}
foreach($arr as $key => $value) {
if(count($value) == 1)
echo $value[0] . '/' . $key;
else
echo implode(", ", $value) . ' ' . $key;
}

Ordering records that are timestamped

I have a tricky one here.
I have a number of results in a table, this table has id, market, date and points.
I want to get all the records for a given month and then output all the points for each day, in order.
I'm not sure of the best way to do this? Her are my options, well my ideas, I could set a loop that will execute for every day of the given month, this will run a query to find every record for that day and will do this for every day of the month, this will then be easy to order a format the records but i'm thinking its not a good idea to query the database that many times.
The second idea i to query the database for all the records for that date, order them by the date. However i can see come problems here when outputting the information for each day, well it will be a long job then the first i think.
Any ideas? anyone done something like this before and could lend a helping hand? Any advise would be more than welcome!
Thanks.
while($row = mysql_fetch_array($getresults))
{
$day = FALSE;
foreach ($row as $row)
{
$day_res = date("Y-m-d H:m:s", strtotime($row["date"]));
if (!$day || $day != $day_res)
{
$day = $day_res;
echo '<h1>'.$day.'</h1>';
}
echo $row['date'] . " " . $row["id"] . ": " . $row["market"] .
"/" . $row["points"] . "<br/>";
}
}
This is the output i get from it:
1970-01-01 00:01:00
3 3: 3/3
3 3: 3/3
2012-01-13 09:01:06
E E: E/E
E E: E/E
1970-01-01 00:01:00
2 2: 2/2
2 2: 2/2
- -: -/-
- -: -/-
1970-01-01 00:01:00
4 4: 4/4
4 4: 4/4
and that more or less repeats for a while.
Thanks again.
If that date is only a date, then you could try something like this:
SELECT t.date, SUM(t.points) FROM table t WHERE date BETWEEN [STARTDATE HERE] AND [ENDDATE HERE] GROUP BY t.date
What it does? It selects everything the date & the sum of the points of that day, because we group all the results based on a day. So for every unique date in your table you will get a row with a result. Use the WHERE date statement to define from which month you need the selection.
Addition: the thing shown is only valid if date is in format like: YYYY-MM-DD. In case you have a timestamp (YYYY-MM-DD HH:ii:ss) you could try to change the query to:
SELECT t.date, SUM(t.points) FROM table t WHERE date BETWEEN [STARTDATE HERE] AND [ENDDATE HERE] GROUP BY DAYOFMONTH(t.date)
This ensures that you will group them by the day of the month (1 to 31) based on the dates from your table.
at first the query to get all for a given month ordered by date:
SELECT * FROM `table` WHERE `date` LIKE '2012-01%' ORDER BY date;
here the php loop to show it:
$day = FALSE;
foreach ($results as $result){
$day_res = date("d", strtotime($result["date"]));
if (!$day || $day != $day_res){
$day = $day_res;
echo '<h1>'.$day.'</h1>';
}
echo $result["id"].": ".$result["market"]."/".$result["points"]."<br/>";
}
Ok here for your structure:
$day = FALSE;
while($row = mysql_fetch_array($getresults))
{
$day_res = date("Y-m-d H:m:s", strtotime($row["date"]));
if (!$day || $day != $day_res)
{
$day = $day_res;
echo '<h1>'.$day.'</h1>';
}
echo $row['date'] . " " . $row["id"] . ": " . $row["market"] .
"/" . $row["points"] . "<br/>";
}

check MySQL database and add for code PHP

I have in PHP:
<?php
$columns = array('mon','thu','wed','tue', 'fri', 'sat', 'sun');
$num_cols = count($columns);
$col = 0;
$datetime = new DateTime("06:00");
echo "<table>"; // border=\"1\" for visible border
// Day header
echo "<tr>";
foreach($columns as $col) {
echo "<td at='$col'>$col</td>";
}
echo "</tr>";
// Times
for($i=0; $i<20; $i++) { // FIXME for more entries or other step width
echo "<tr>";
$datetime->modify('+30 minutes');
for ($j=0; $j<$num_cols; $j++)
echo '<td class="' . $datetime->format('H:i') . '">' . $datetime->format('H:i') . '</td>';
echo "</tr>";
}
echo "</table>";
?>
and in database MySQL:
id | day | hours
1 | mon | 07:00
2 | thu | 08:40
3 | wed | 12:30
4 | thu | 13:00
5 | fri | 05:00
etc
how is the best method for checking this? If date is in database then i would like make TD with red background, for example add class red:
echo "<td at='$col' class='red'>$col</td>";
Check this in each loop FOR is not good idea - this generated to many query for database.
How can i make it?
I can use also jquery and for example JSON if this is possible.
List them all in a keyed array, then when looping through the calendar simply check for these keys.
For example, you'd get the array array(1 => array('07:00' => true)) (day of the week => appointments).
You can then check isset($array[$datetime->format('N')][$datetime->format('H:i')])

Categories