I had to come up with this post because I’ve been working on an old CMS about 3 years old (or even more) and I had been wondering why the calendar links cuts off from 2001 to 2003.
Task: List a year/month links from the present to the oldest published image sets.
Sounds easy, and I believe it is.
But when I checked on the existing script, this is what I got.
$month_array = array("1"=>'January',"2"=>'February',"3"=>'March',"4"=>'April',"5"=>'May',"6"=>'June',"7"=>'July',"8"=>'August',"9"=>'September',"10"=>'October',"11"=>'November',"12"=>'December'); $smarty->assign('y2day',$y2day); $y=0; for ($q=12; $q >= 1; $q--){ $month = $month_array[$q]; if( ($_GET[year] < '2000') && ($m2day ==$q ) ) $w_string = $week_string; else $w_string =''; if( ($_GET[year] == '2007') && ($_GET[month] == $q) ) $w_string = $week_string; if($m2day >= $q){ $tmp_cal_month_now_array = array( 'month' => $month, 'string' => $w_string, 'link' => $q ); $date_month_now_array[$y++] = $tmp_cal_month_now_array; } } //for $smarty->assign('calendar_now_month',$date_month_now_array); $y=0; $c_yeartoday = date("Y") -1; //echo $c_yeartoday; for($q=0; $q < = 5; $q++){ $tmp =$c_yeartoday - $q; //echo $tmp; $tmp_cal_date_array = array( 'year' => $tmp ); $date_year_array[$y++] = $tmp_cal_date_array; } //for $smarty->assign('calendar_year',$date_year_array); $y=0; for($q=12; $q >= 1; $q--) { $month = $month_array[$q]; if( $_GET[month] == $q ) $w_string = $week_string; else $w_string=''; $tmp_cal_month_array = array( 'month' => $month, 'string' => $w_string, 'link' => $q ); $date_month_array[$y++] = $tmp_cal_month_array; }//for $smarty->assign('calendar_month',$date_month_array); $y=0; for($q=12; $q >= 10; $q--) { $month = $month_array[$q]; if( ($_GET[year] == '2000') && ($_GET[month] == $q) ) $w_string = $week_string; else $w_string=''; $tmp_cal_month_old_array = array( 'month' => $month, 'string' => $w_string, 'link' => $q ); $date_month_old_array[$y++] = $tmp_cal_month_old_array; }//for $smarty->assign('calendar_month_old',$date_month_old_array);
Looking at the above script, it looks like they were grouped in to 4 sections, deriving the values of $date_month_now_array, $date_year_array, $date_month_array and $date_month_old_array. And the hardcoded values ’2000′ and ’2007′ will definitely set limit and obviously introduce bug, and so it did. Honestly, I would have coded it this way when I was moving into PHP 3 years ago, and perhaps even now if I’d have been coding for a whole day confronted with bugs.
Anyway, the main problem with the above code is, there was always a reference for dates and the original programmer didn’t use it, the date column in the content’s table. Instead, I’m guessing, he setup a start ‘year’ which is probably he asked someone about the oldest possible year a content was published – there he arrived at using ’2000′ in the code. And if I’m not mistaken, this code was written in 2007, LOL, so there was a condition on year set to 2007.
Here’s how I modified it, optimized it as much (well I hope). The date column had a unix timestamp values, so it’s not in typical date format.
/** * Calendar modification * @author marvin marcelo * @uses ez_sql * @link http://www.phpclasses.org/browse/package/790.html */ /* present */ list($y, $m, $d) = explode(" ", date("Y n j")); $sql = "select distinct(from_unixtime(updateStartDate, '%Y')) year from series_table where updateStartDate > 0 order by updateStartDate desc"; /* ezSql stuff */ $years = $db->get_results($sql, ARRAY_A); for ($i = 0; $i < count($years); ++$i) { $months = array(); for ($j = 12; $j > 0; --$j) { $endofmonth = date("t", strtotime("{$years[$i]["year"]}-$j-1")); if ($years[$i]["year"] == $y && $j > $m) { continue; /* future year-month */ } if ($years[$i]["year"] == $y && $j == $m) { /* this day in this month of this year is also future, use current date instead */ $endofmonth = $d; } $ts0 = strtotime("{$years[$i]["year"]}-$j-1"); /* unix timestamp start of month */ $ts1 = strtotime("{$years[$i]["year"]}-$j-$endofmonth"); /* unix timestamp last day or today of month */ if ($db->get_row("select * from series_table where updateStartDate > $ts0 and updateStartDate < = $ts1")) { if ($year == $years[$i]["year"] && $j == $month) { $months[] = array("active" => "1", "j" => $j, "F" => date("F", $ts0)); } else { $months[] = array("j" => $j, "F" => date("F", $ts0)); } } } if (count($months)) { $years[$i]["months"] = $months; } } /* template */ $smarty->assign('calendar', $years); /** * Calendar modification end block */
The process I did …
- Select distinct years from all published content by converting unix timestamp to readable year value, then iterate on them
- Do a for loop from 12 (december) to 1 (january) to generate a unix timestamp for use in the next query
- Query the table for a matching timestamp of the first day and the last day of month-year pair; Use current day of month if iterating year and month matches the present
- Show the month link for the year in iteration if a match is found
Couple of notes though, I didn’t name the table as ‘series_table’
, it’s been there years since. I also named my variables when referring to start and end as $x0 and $x1, $ts0 and $ts1. I got used to this when college years in physics – the start and end of a distance, I don’t know, I just like the thought
.
Hope it didn’t went order to chaos at all!
Tags: basic programming, calendar, ezsql, grumble, month-year, php, smarty


