add css class to mysql result based on criterias - php

I populate a list of dates from a MySQLdatabase like this:
<?php
while ($row = mysql_fetch_array($list_customers)) {
echo "<tr>\n";
echo "<td>".$row['customer_date']."</td>\n";
echo "</tr>\n";
}
?>
Now I would like to add the result inside a <span> that changes class='' based on some criteria:
If date result is within a 30 days reach from todays date, add
class='yellow'
If date result is over 30 days from today, add class='green'
If date result has passed, based on todays date, add class='red'
Would this be possible? Thanks in advance.

Yes it is. Just compare your date with current time using a series of if statements and assign a variable to the class name, like this:
while ($row = mysql_fetch_query($list_customers)) {
echo "<tr>\n";
$class = "class='green'";
if (strtotime($row['customer_date']) < time()) {
$class = "class='red'";
}elseif (strtotime($row['customer_date']) < time() + 30*24*3600) {
$class = "class='yellow'";
}
echo "<td><span $class>" . $row['customer_date'] . "</span></td>\n";
echo "</tr>\n";
}

It's really just a simple case of writing the if() conditions you specified. There's no magic to it.
Firstly, we need to know what format your customer_date field is in. Since you're printing it directly into the HTML code I guess it's in a text format, so the first thing we need to do is convert it to a date object.
$custDate = new DateTime($row['customer_date']);
This will only work if the date is in a suitable format, but to be honest if it isn't in standard MySQL date format then you should stop now and fix that before we go any further.
You'll also need the current date as a date object:
$currDate = new DateTime();
Now you can compare them easily enough using the methods on the DateTime class:
$dateDiff = $currDate->diff($custDate)->days;
Now you've got that, you can just do your if() conditions.
However, I would note a few things:
You're using mysql_fetch_array(). Please note that the mysql_ functions are considered obsolete; you should replace with mysqli_xxx or the PDO library wherever possible.
You suggest putting the class into a <span> inside the <td> -- it is possible to put the class directly into the <td>. This would be a cleaner option, so I'll use that in the answer, though it is up to you.
You suggest using class names red, green, yellow. Please note that this is not a particularly good use of class names. Class names should reflect what the element is actually for, rather than how it looks. This is because the whole point of using classes and separating the styles away from the HTML is so that the styles can be changed without needing to alter the HTML. But if the class names are just colour names, it ties it logically to that colour; you may just as well put the colours directly into the HTML. Better choices of class name would perhaps be something like custExpired, custNearlyExpired, etc. That would give you more flexibility later, and make the code easier to understand for anyone reading it (eg the google bot!).
So with all that in mind, here's some code for you:
$currDate = new DateTime();
while ($row = $mysqli->fetch_array($list_customers)) {
$custDate = new DateTime($row['customer_date']);
$dateDiff = $currDate->diff($custDate)->days;
$class = '';
if($dateDiff < 30) { $class = 'custNearlyExpired'; }
if($dateDiff < 0) { $class = 'custExpired'; }
echo "<td class='custDate {$class}>{$row['customer_date']}</td>\n";
}
and CSS:
td.custDate {
background: green;
}
td.custDate.custNearlyExpired {
background: yellow;
}
td.custDate.custExpired {
background: red;
}
Hope that helps.

Related

Symfony 6.0 time format problem database upload

There were some problems with symfony over time. unfortunately, this is not the first time I have run into this. Has anyone ever encountered this problem? If so, thank you for your help.
Controller.php
if($xml = simplexml_load_file($feedUrl)) {
$result["chanel"] = $xml->xpath("/rss/channel/item");
foreach($result as $key => $attribute) {
$i=0;
foreach($attribute as $element) {
$ret[$i]['title'] = (string)$element->title;
$ret[$i]['category'] = (string)$element->category;
$ret[$i]['link'] = (string)$element->link;
$ret[$i]['pubDate'] = json_decode(json_encode($element->pubDate), TRUE);
$ret[$i]['enclosure'] = (array)$element->enclosure;
$ret[$i]['description'] = (string)$element->description;
$i++;
}
}
}
foreach ($ret as $feed){
$newnews = new Newsfeed();
$newnews->setTitle($feed['title']);
$newnews->setCategory($feed['category']);
$newnews->setLink($feed['link']);
$newnews->setDescription($feed['description']);
$newnews->setDate(date("Y-m-d h:i:sa", strtotime($feed['pubDate'][0])));
$newnews->setImage($feed['enclosure']['#attributes']['url']);
$newnews->setSource('2');
$entityManager->persist($newnews);
$entityManager->flush();
}
This problem
The date() function returns a string, so this line won't work:
$newnews->setDate(date("Y-m-d h:i:sa", strtotime($feed['pubDate'][0])));
You can probably just use:
$newnews->setDate(new \DateTimeImmutable($feed['pubDate'][0]));
I have had this problem before. For me, when working with only Dates (no time) it was kind of misleading the fact that MySQL and thus doctrine annotations have the Date type, but PHP/Symfony does not.
As mentioned by Chris, the date() function returns a string, but the class DateTime is your friend here.
Even when it is called DateTime, this class allows formatting and you can indeed, for example, retrieve only a date with it. An example would be:
$date = new DateTime('2000-01-01 12:30:25');
echo $date->format('Y-m-d');
Or in your case, in which you DO want to return the time part too:
$pubDate = new DateTime($feed['pubDate'][0])->format('Y-m-d h:i:sa');
$newnews->setDate($pubDate);
Which can be easily transformed into a one-liner.
This will show only what you ask for in the format() function.
There is one trickiness though. In my country at least, it is very common to format dates with a slash (/), but DateTime->format() will not work with Y/m/d, so keep it in mind and check for the correct format here if you are going to be using slashes.

Creating a chat with Laravel

Good night !
I managed to show information about users and content of the messages with the following code
Route::get('chat', function(){
// Get the number of days to show data for, with a default of 7
$usr1 = 121;
$usr2 = 123;
/***Obtener conversacion 121 y 123**/
$messageuser = MessageUser::with('conversaciones')->get();
foreach($messageuser as $msj){
if(($msj->id_emisor == $usr1)&&($msj->id_receptor == $usr2)){
$usuario1 = User::find($usr1);
foreach($msj->conversaciones as $conv){
echo $usuario1->name;
echo $conv->contenido;
}
}
if(($msj->id_emisor == $usr2)&&($msj->id_receptor == $usr1)){
$usuario2= User::find($usr2);
foreach($msj->conversaciones as $conv){
echo $usuario2->name;
echo $conv->contenido;
}
}
}
});
Now , I need to join this two condition into array to send the result to view , I don't know how to create this array , someone would be kind enough to help me with this ?
I would try and use the MVC architecture that Laravel is designed for in order to help you organise your code.
If your variable values are within the MessageUser model then you can easily query them without doing your if statements. If your want to keep with you style of logic then you can easily loop using a foreach within the view and then echo using double curly brackets to echo the results.

I need help sorting out an if statement in a simplexml statement

Some basic background ...
I have a form that enters data to an xml file and another page that displays the data from teh xml depending that it meets the requirements . All of this I have managed to get done and thanks to a member on here I got it to show only the data as long as it has todays date and status is out . But I am left with the problem of trying to sort an if statement which needs to show data if it has it or show another div if not .
My Code ...
$lib = simplexml_load_file("sample.xml");
$today = date("m/d/y");
$query = $lib->xpath("//entry[.//date[contains(., '$today')]] | //entry[.//status[contains(., 'out')]]");
foreach($query as $node){
echo "<div id='one'>$node->name</div>
<div id='two'>$node->notes</div>
<div id='three'><div class='front'>$node->comments</div></div>";
}
So to reiterate if query returns matched data do the foreach else show another div
I only wish to know the right code for the if else statement if soneone could help with this I would be very grateful and will up vote any answer as soon as I have the reputation in place . I also apologise in advance if the question has been asked before or if it is too vague thanks again .
If xpath fails to resolve the path, it will return false (see here). Wrap the foreach loop in a simple check:
if( $query ) {
foreach($query as $node){
...
}
}
else {
// Echo the special div.
}
Since PHP is loose typed, if xpath happens to return an empty array, this check will also handle that case. Be aware that if the xpath call does return false, there may be a separate error at play that may require additional or alternative handling.

Using multiple values with strstr($_SERVER['PHP_SELF']...)

another simple thing that's got me stuck:
I'm using the following to check on the current url and select a div class dependent on the result:
$checkit = $_SERVER['PHP_SELF'];
...
<li "; if(strstr($checkit,'welcome')) { echo "class='active_tab'"; }...
What I want to be able to do is also check if the url includes other words which would also require that same 'li' item to be given the 'active_tab' class, but i can't figure out the format. Something like this, although obviously this doesn't work:
<li "; if(strstr($checkit,'welcome', 'home', 'yourprofile')) { echo "class='active_tab'"; }...
Can someone help?
I know there's a better way but stop-gap fix would be:
$searchStrings = array('welcome','home','yourprofile');
$stringFound = false;
foreach($searchStrings as $checkString)
{
if(strstr($checkit, $checkString))
{
$stringFound = true;
break;
}
}
Then use $stringFound to change your output.
Edit 1: Switched continuefor break thanks ZombieHunter (It's late -_-)
Edit 2: Alternatively you can use a regular expression (though I think that's overkill here)
if(preg_match('/(welcome|home|your profile)/',$checkit))
{
// Do your stuff here
}
But this is not as expressive (easier to read and extend an array) and if those values start piling up its easier to hook the array into some storage like DB query.

PHP DOM parser get data from a span

I am trying to use DOM to get the days and times and also the rooms (im actually getting everything in my script but its getting these two im having trouble with) from the following batch of HTML:
</td><td class="call">
<span>12549<br/></span>View Book Info
</td><td>
<span id="ctl10_gv_sectionTable_ctl03_lblDays">F:1000AM - 1125AM<br />T:230PM - 355PM</span>
</td><td class="room">
<span id="ctl10_gv_sectionTable_ctl03_lblRoom">KUPF106<br />KUPF106</span>
</td><td class="status"><span id="ctl10_gv_sectionTable_ctl03_lblStatus" class="red">Closed</span></td><td class="max">20</td><td class="now">49</td><td class="instructor">
Schoenebeck Kar
</td><td class="credits">3.00</td>
</tr><tr class="sectionRow">
<td class="section">
101<br />
Here is what I have so far for finding days
$tracker =0;
// DAYS AND TIMES
$number = 3;
$digit = "0";
while($tracker<$numSections){
$strNum = strval($number);
$zero = strval($digit);
$start = "ctl10_gv_sectionTable_ctl";
$end = "_lblDays";
$id = $start.$zero.$strNum.$end;
//$days = $html->find('span.$id');
$days=$html->getElementByTagName('span')->getElementById($id);
echo "Days : ";
echo $days[0] . '<br>';
$tracker++;
$number++;
if($number >9){
$digit = "1";
$number=0;
}
}
as you can see from the HTML, the site im parsing has pretty unique ID's for some of its spans (ctl10_gv_sectionTable_ctl03_lblRoom). As I only posted 1 section's HTML block, what you don't see is that the code for the next class section is identical except for the "ctl03" part, which is what all the extra code I have takes care of, just so no one is thrown off by it.
I've tried a few different ways but can not seem to get the days (i.e. "1000AM - 1125AM") or the rooms (i.e. KUPF106). The rest of the stuff is pretty simple to grab but these two don't have class identifiers or even a td identifier. I think I just need to know how to use the value I have in $id as the specific span id I am looking for? If so can someone show me how to do that?
This:
$html->getElementByTagName('span')->getElementById($id);
makes no sense. getElementByTagName returns a DOMList, which does not have a getElementById method.
I think you mean $html->getElementById($id);, but I can't be sure because I don't know what $html is.
Once you have the element, you can get the text value with $element->textContent if you don't need to walk among the text nodes.
Have you considered using DOMXPath for your parsing task? It's probably much easier and clearer.
Simple Html Dom should be avoided unless you're using Php version <= 4. The built in Dom functions in Php5 use the much more reliable libxml2 library.
The proper way to iterate that html is to first identify the rows to iterate and then write xpath expressions to pull the data relative to that row.
$dom = new DOMDocument();
#$dom->loadHTML($html);
$xpath = new DomXpath($dom);
foreach($xpath->query("//tr[#class='sectionRow']") as $row){
echo $xpath->query(".//span[contains(#id,'Days')]",$row)->item(0)->nodeValue."\n";
echo $xpath->query(".//span[contains(#id,'Room')]",$row)->item(0)->nodeValue."\n";
echo $xpath->query(".//span[contains(#id,'Status')]",$row)->item(0)->nodeValue."\n";
}

Categories