Need some help, been going around this for ages, but just cant seem to solve it. I've got some data in a field called "Term Year PrNo". The data in this field is like below:
[2010-201110]Winter - 2010 - 1st
[2010-201111]Winter - 2010 - 2nd
[2010-201120]Spring - 2011 - 1st
[2010-201121]Spring - 2011 - 2nd
[2010-201130]Summer - 2011 - 1st
[2010-201131]Summer - 2011 - 2nd
[2011-201210]Winter - 2011 - 1st
[2011-201211]Winter - 2011 - 2nd
[2011-201220]Spring - 2012 - 1st
[2011-201221]Spring - 2012 - 2nd
[2011-201230]Summer - 2012 - 1st
[2011-201231]Summer - 2012 - 2nd
[2012-201310]Winter - 2012 - 1st
[2012-201311]Winter - 2012 - 2nd
[2012-201320]Spring - 2013 - 1st
[2012-201321]Spring - 2013 - 2nd
[2012-201330]Summer - 2013 - 1st
I need to make each row of data in that field a radio button selection, which I've managed to do by sticking the contents of the field and spitting it out as an input field. I've also used regex to clean the look of the input value - i.e. remove the first sort field. So far so good. The problem I cant seem to solve is I need to break the data down in segments and wrap them around a div class called yearblock based on the years, 2010-2011 | 2011-2012 | 2012-2013, so that I can arrange them nicely using CSS. I've managed to figure out how to start div class, by comparing previous year to current year, but I cant seem to figure out how to appropriately put the end in after echoing out my input. Hope this makes sense, can someone look at my code and point me in the right direction please?
<?php
$arrayTermdates = array();
foreach($termsResult->getRecords() as $key => $term)
{
$arrayTermdates[] = $term->getField('Term Year PrNo');
}
$arrayTermdates = array_unique($arrayTermdates);
sort($arrayTermdates, SORT_STRING | SORT_FLAG_CASE);
foreach($arrayTermdates as $termdate)
{
preg_match_all("/\[[^)]+\]/",$termdate,$matches);
$year = str_replace('[', '', $matches[0][0]);
$year = str_replace(']', '', $year);
$year = str_replace(' ', '', substr($year, 0, -2));
$termdate = preg_replace("/\[[^)]+\]/","",$termdate);
/*
/ - opening delimiter (necessary for regular expressions, can be any character that doesn't appear in the regular expression
\[ - Match an opening parenthesis
[^)]+ - Match 1 or more character that is not a closing parenthesis
\] - Match a closing parenthesis
/ - Closing delimiter
*/
if ($previousYear != $year || $previousYear == '')
{
echo '<div class="yearblock">';
echo '<strong>'.$year.'</strong><br />';
}
?>
<div class="term_value_list">
<input name="Termdate[]" type="radio" value="<?php echo $termdate; ?>">
<?php
$TermdatesArray = explode('-',$termdate);
$Termdisplay = $TermdatesArray[0].' '.$TermdatesArray[1].' ['.str_replace(' ', '', $TermdatesArray[2]).' PR]';
echo $Termdisplay;
?>
<!-- I need to echo an </div> for div class yearblock -->
You're almost there. I'm going to make a little simplification to your code to get rid of the regexp, however.
First off, we are going to initiate a year tracker. This will allow us to keep track of which year we are in.
$myCurrentYear = false;
From there, we'll loop through your rows. The first check we will do is to check if the year is different. If it is, and the current year was not false, we'll output a </div>. Then, if it was different, we'll print headers for the new year.
foreach ($arrayTermdates as $date) {
$newdate = split("-",substr($date,strpos($date,"]")+1));
// Gotta remember to trim stuff
$year = (int)trim($newdate[1]);
if ($year != $myCurrentYear) {
if ($myCurrentYear !== false) {
echo "</div>";
}
$myCurrentYear = $year;
echo "<div class='yearblock'><strong>Year ".$myCurrentYear."-".($myCurrentYear+1)."</strong>:";
}
// Do your processing here
}
// NOTE: the last one won't be closed. We'll close it here
if ($myCurrentYear !== false) {
echo "</div>";
}
Start your first div before the first output:
echo '<div class="yearblock">';
Then close the block and open a new one each time your if() condition is true:
if ($previousYear != $year || $previousYear == '')
{
echo '</div><div class="yearblock">';
echo '<strong>'.$year.'</strong><br />';
}
And finally, close the final div after you have finished creating output:
echo '</div>';
Related
I need to check if entered date is between 2019-09-01 - 2019-12-31
I can do this as follows: $koodi is user input
$pattern1 = "/^2019-(09|11)-([0-2][0-9]|30)$/";
$pattern2 = "/^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
if(preg_match($pattern1, $koodi) || preg_match($pattern2, $koodi)) {
echo "<code>$koodi</code> ok!<br>\n";
}
else {
echo ("<code>$koodi</code> NOT ok!<br>\n");
}
I was trying to make those two conditions into single regex statement, is that possible and if so how?
I tried:
$pattern = "/^2019-(09|11)-([0-2][0-9]|30)$ | ^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
Did not work, neither the following where i tried to put parentheses around conditions:
$pattern = "/(^2019-(09|11)-([0-2][0-9]|30)$) | (^2019-(10|12)-([0-2][0-9]|3[0-1])$)/";
Please don't use a regex to do that, what if the dates change or what if the next developer has to come and work on this and figure out what your doing?
According to this article you can check if a date is between 2 dates by doing something like this.
<?php
$currentDate = date('Y-m-d');
$currentDate = date('Y-m-d', strtotime($currentDate));
$startDate = date('Y-m-d', strtotime("01/09/2019"));
$endDate = date('Y-m-d', strtotime("01/10/2019"));
if (($currentDate >= $startDate) && ($currentDate <= $endDate)){
echo "Current date is between two dates";
}else{
echo "Current date is not between two dates";
}
as for why your patterns didn't work its because you have a space around the pipe in the middle and you may possibly need to wrap the whole thing in brackets. You also have the $ half way through the regex which is matching the whole string, I would usually only have it at the end, like this: -
^(regex1|regex2)$
I haven't written the correct version in case your tempted to use it, (please use the date objects method)
Let say currentmonth is 06 and currentyear 2017
i have dropdown of year and month ..
if i select year 2017 and month of July which is larger then currentmonth
how do i show there is not data available yet
my current code..and its not working..i'm a newbie and not sure im doing this right or not...
$mystartingyear=2017;
$mystartingmonth=01;
$currentmonth=date("m");
$currentyear=date("Y");
if ($currentyear >= $mystartingyear && $currentmonth >= $mystartingmonth)
{
echo "Show Data";
}
else
{
echo "No Data yet";
}
i also tried it like this
$mystartingyear=2017;
$mystartingmonth='01';
$currentmonth=12;
$currentyear=2017;
//$currentmonth=date("m");
//$currentyear=date("Y");
if ($currentyear >= $mystartingyear && $currentmonth >= $mystartingmonth)
{
echo "Show Data";
}
else
{
echo "No Data yet";
}
it always display "show data"
Edit:
Integers from 01 to 07 are ok just as long as you don't do 010 (with 3 integers) since that will be represented as 8. But as soon as you start hitting 08 and 09 for the months of August and September (which may be what's in your unknown dropdown), you will have problems.
So it's best you quote it.
Consult "Footnotes".
Original answer:
The leading zero in 01 for:
$mystartingmonth = 01;
^^
is treated as an octal.
It needs to be quoted:
$mystartingmonth = '01';
Octals references:
http://php.net/manual/en/language.types.integer.php
https://en.wikipedia.org/wiki/Octal
Footnotes:
If your current code is failing you, then something else is failing you.
You mention in your question that you're using this from a dropdown and that code wasn't included, nor how it's being passed.
Use PHP's error reporting, set to catch and display:
http://php.net/manual/en/function.error-reporting.php
Verify your conditional statement's logic also; both conditions must be met.
There is missing semicolon after first echo i.e. code should be
echo "Show Data";
Then every thing should work fine,
The date(); function in php returns the date in string and when you compare a string with integer it is implicitly converted into equivalent integer variable,if you want for sure you can use intvar(); function which converts variable to equivalent integer.But in your case it is not necessary.For more about i recommend you to read php manual .
I am creating a calendar function in php. Along with the function I need a "previous" and "next" link that show the previous or next month using the GET method. The links don't work the way I expect them to. From what I've found through debugging it doesn't look like it's actually adding or subtracting 1 from month.
This is currently what I have:
$month=$_GET["month"];//should initially set them to null?
$year=$_GET["year"];
//previous and next links
echo "<a href='calendar.php?month=<?php echo ($month-1)?>'>Previous</a>";
echo "<a href='calendar.php?month=<?php echo ($month+1)?>'>Next</a>";
//Calls calendar method that returns the calendar in a string
$calDisplay=calendar($month,$year);
echo $calDisplay;
PHP doesn't do calculations inside strings and doesn't parse PHP tags inside strings. You are already in 'PHP mode', and opening another PHP tag inside the string just outputs that tag as you may have noticed when you inspected the link in your browser.
Instead, try closing the string, concatenating the next/previous month (using the dot operator), and concatenating the last part of the link:
//previous and next links
echo "<a href='calendar.php?month=" . ($month-1) . "'>Previous</a>";
echo "<a href='calendar.php?month=" . ($month+1) . "'>Next</a>";
You can also calculate the values into variables first, because simple variables can be used inside double-quoted strings:
//previous and next links
$previousMonth = $month-1;
$nextMonth = $month+1;
echo "<a href='calendar.php?month=$previousMonth'>Previous</a>";
echo "<a href='calendar.php?month=$nextMonth'>Next</a>";
On the first request, you may not have a month at all, so you may want to check for that too, for instance using isset.
$month = 1;
if (isset($_GET['month'])) {
$month = (int)$_GET['month'];
}
As you can see, I already did an (int) typecast there too. Combining this with the variables version, allows you to make the code a little more solid by performing some checks on the input, and only output the previous/next links if they make sense.
$month = 1;
if (isset($_GET['month'])) {
$month = (int)$_GET['month'];
}
if ($month < 1 || $month > 12) {
// Invalid month. You can choose to throw an exception, or just
// ignore it and use a default, like this;
$month = 1;
}
//previous and next links, if necessary.
$previousMonth = $month-1;
$nextMonth = $month+1;
if ($previousMonth >= 0) {
echo "<a href='calendar.php?month=$previousMonth'>Previous</a>";
}
if ($nextMonth <= 12) {
echo "<a href='calendar.php?month=$nextMonth'>Next</a>";
}
Oh, and a minor detail. Personally I don't like to put 'big' chunks of HTML inside a string, so I'd rather use some template, or at least write it like this. As you can see, you can close and open PHP tags (just not inside strings), so you can output plain HTML from within your PHP code. The <?= $x ?> notation is a shorthand for <? echo $x; ?>.
//previous and next links, if necessary.
$previousMonth = $month-1;
$nextMonth = $month+1;
if ($previousMonth >= 0) {?>
<a href='calendar.php?month=<?=$previousMonth?>'>Previous</a>
<?php}
if ($nextMonth <= 12) {?>
<a href='calendar.php?month=<?=$nextMonth?>'>Next</a>
<?}
Try doing something like the following:
echo sprintf('Previous', http_build_query(array('month' => $month - 1)));
echo sprintf('Next', http_build_query(array('month' => $month + 1)));
While it seems more convoluted, it serves two purposes.
Its cleaner and less messing around with string concatination
You get to learn about sprintf and http_build_query functions which can be very useful in certain situations. sprintf is a string formatting function which basically takes a string as its first parameter and substitutes certain tokens with the next n parameters. In this example, %s is a token which means replace it with a string, which is passed as the second function. http_build_query takes an associative array and builds a http query from it. So in the code above, the http_build_query function will return month=11 (assuming the month was 12) for the Previous link. You can also add multiple array parameters and it will build the query string with the ampersands.
While the other answers do what you need, its always wise to look at and understand other PHP functions.
The $_SERVER REQUEST METHOD when you click on a link is 'GET'.
use the parse_str function and place your $_GET keys and variables into an array.
parse_str($_SERVER['QUERY_STRING'],$output);
print_r($output);
Maybe you can test for that. Is this what you are looking for?
Since everything you send via request is considered a String, try this casting integer.
HTML
<!-- previous and next links -->
<a href='calendar.php?month=<?php echo ((int)$month - 1)?>'>Previous</a>
<a href='calendar.php?month=<?php echo ((int)$month + 1)?>'>Next</a>
Test case scenario - User clicks on one of two links: 2012/10, or 2012/10/15.
I need to know whether the DAY is specified within the link. I am already stripping the rest of the link (except above) out of my URL, am I am passing the value to an AJAX request to change days on an archive page.
I can do this in either JS or PHP - is checking against the regex /\d{4}\/\d{2}\/\d{2}/ the only approach to seeing if the day was specified or not?
You can also do this if you always get this format: 2012/10 or 2012/10/15
if( str.split("/").length == 3 ) { }
But than there is no guaranty it will be numbers. If you want to be sure they are numbers you do need that kind of regex to match the String.
You could explode the date by the "/" delimiter, then count the items:
$str = "2012/10";
$str2 = "2012/10/5";
echo count(explode("/", $str)); // 2
echo count(explode("/", $str2)); // 3
Or, turn it into a function:
<?php
function getDateParts($date) {
$date = explode("/", $date);
$y = !empty($date[0]) ? $date[0] : date("Y");
$m = !empty($date[1]) ? $date[1] : date("m");
$d = !empty($date[2]) ? $date[2] : date("d");
return array($y, $m, $d);
}
?>
I would personally use a regex, it is a great way of testing this sort of thing. Alternatively, you can split/implode the string on /, you will have an array of 3 strings (hopefully) which you can then test. I'd probably use that technique if I was going to do work with it later.
The easiest and fastest way is to check the length of the string!
In fact, you need to distinguish between: yyyy/mm/dd (which is 10 characters long) and yyyy/mm (which is 7 characters).
if(strlen($str) > 7) {
// Contains day
}
else {
// Does not contain day
}
This will work EVEN if you do not use leading zeros!
In fact:
2013/7/6 -> 8 characters (> 7 -> success)
2013/7 -> 6 characters (< 7 -> success)
This is certainly the fastest code too, as it does not require PHP to iterate over the whole string (as using explode() does).
Particularly, 08 and 09 have caused me some major trouble. Is this a PHP bug?
Explanation:
I have a calendar 'widget' on a couple of our client's sites, where we have a HTML hard-coded calendar (I know a PHP function can generate n number of months, but the boss man said 'no').
Within each day, there is a PHP function to check for events on that day, passing the current day of the month like so:
<td valign="top">01<?php printShowLink(01, $events) ?></td>
$events is an array of all events on that month, and the function checks if an event is on that day:
function printShowLink($dayOfMonth, $eventsArray) {
$show = array();
$printedEvent = array();
$daysWithEvents = array();
foreach($eventsArray as $event) {
if($dayOfMonth == $event['day'] && !in_array($event['id'], $printedEvent)){
if(in_array($event['day'], $daysWithEvents)) {
echo '<hr class="calendarLine" />';
} else {
echo '<br />';
}
$daysWithEvents[] = $event['day']; // string parsed from timestamp
if($event['linked'] != 1) {
echo '<div class="center cal_event '.$event['class'].'" id="center"><span title="'.$event['title'].'" style="color:#666666;">'.$event['shorttitle'].'</span></div>';
$printedEvent[] = $event['id'];
} else {
echo '<div class="center cal_event '.$event['class'].'" id="center">'.$event['shorttitle'].'</div>';
$printedEvent[] = $event['id'];
}
}
}
}
On the 8th and 9th, no events will show up. Passing a string of the day instead of a zero-padded integer causes the same problem.
The solution is as what is should have been in the first place, a non-padded integer. However, my question is, have you seen this odd behavior with 08 and/or 09?
I googled this and couldn't find anything out there.
Quote it. 0123 without quotes is octal in PHP. It's in the docs
$ php -r 'echo 01234, "\n01234\n";'
668
01234
$
So you should change your code to
<td valign="top">01<?php printShowLink('01', $events) ?></td>
It's been a while since I've had to wade through so much PHP been doing mostly Javascript for 3 years. But 08 and 09 being a problem makes me think: they could be getting treated as octal (base 8), and the digits 8 and 9 do not exist in octal.