BvSiT

The waste calendar web site: a PHP application

The waste calendar web application provides easily accessible information about the waste collection calendar for Verrières-le-Buisson, a commune – more or less the equivalent of a UK county or district - located some 15 km south of Paris with a population of about 15.000 inhabitants.

In this commune there exist five different types of house-to-house collections. Most of the waste types are characterized by the color of the used garbage bin. E.g. the dark green bin is reserved for household garbage as the yellow bin is intended for the collection of paper and plastics. These two waste types are collected weekly. The other waste types are organized by sector. The commune is divided in sectors. The location of an address within a certain sector will determine day and frequency of the collection. All the information is provided for in a PDF flyer and also announced in the local monthly magazine.

For new residents it can take some time before one has a general idea of collection days and times. The purpose of my web application is to provide quick per-address up-to-date information about each waste collection.

See the live web application at www.bvsit.nl/calendrierdecollecte

The entire source code can be found at github.com/BvSiT

Used techniques

The application is created with PHP. No framework like e.g. Symfony was used. Front-end techniques used were JavaScript, JQuery, Bootstrap and CSS. A MySQL database provides the waste collection info. Information was gathered from the PDF flyer and added to the database by parsing it once with PHP.

A simple form of dependency injection as described in Learn PHP 7 by Steve Prettyman was applied in an adapted form. All objects are created by using a Container object which also handles all other dependencies. The application uses two central classes. Once the user has chosen an address a waste_col_calendar object is created which collects all the relevant information for the particular address: collection day and time for each waste type and first coming waste collections.

To create the page with the year calendar and coming events for each month a month_cal object is created. This object creates the HTML code to present the months. Collection dates are represented as colored dots.

Creating the colored dots

In the month calendar collection dates are presented as colored dots. How was this accomplished?

Creating a colored circle can simply be done by using a HTML div element with the following CSS class to which then a background color is added:

.color-dot {
	border-radius: 20px;
	border: none;
	width: 20px;
	height: 20px;
} 

All waste types are represented by a color and a code represented in CSS like this:

.darkgreen,.DGB{      /*dark green bin */
	background: #009900; /*dark green*/	
	color:white;
}
.yellow,.YEB {	/*yellow bin*/
	background: #ffd64c;
}
.green,.GRB {	/*green bin*/
	background: #33ff33; /*middle green*/
}

.red,.BUL {	/*bulk waste*/
	background: #ff0000;
}

.lightgreen,.SAC { /* garden waste bag */		
	background: #bfd954;
}

.EXC{ 	/*excluded date*/
	background: #F5F5F5; /*HTML WhiteSmoke*/
}

For a date with only one collection and thus one color the HTML code created by PHP will look like this:

6

Notice also the code to create a Bootstrap tooltip.

To create a colored dot with two waste types the PHP code creates a background with a 50%-50% linear-gradient

5

In this case we need the HTML color code which is read by a PHP function get_background_colors() from the CSS file.


public static function get_background_colors($path_css,$col_dates){
	/* If there exist duplicate dates in $col_dates get the color code for classes from corresponding waste type code from css
	*  $col_dates = array('DGB'=>array('2018-01-01','2018-03-23',...),'YEB'=>...etc.)
	*  Return array('DGB'=>'#02ad79','YEB'=>..)	
	*/
	$arr_css=null;	
	$background_colors=null;
	foreach ($col_dates as $waste_type=>$dates){
		$keys=$col_dates;
		unset($keys[$waste_type]); //compare only with other waste types
		foreach($keys as $waste_type_2=>$val){
			foreach($dates as $date){ //dates belonging to $waste_type
				if ( in_array($date,$col_dates[$waste_type_2]) ){ //if the same date exists for the two waste types
					if (!$arr_css){
						$arr_css=self::parse_css($path_css);
					}
					if ( isset($arr_css['.'.$waste_type]['background']) ){
						$background_colors[$waste_type]=$arr_css['.'.$waste_type]['background'];
					}
				}
			}
		}
	}
	return $background_colors;
}

Creating a color dot with three colors

It is not possible to create a dot with three colors using a HTML linear-gradient. To achieve this we use the HTML canvas element in combination with JavaScript to draw the graphics.

Code is added by PHP to the HTML calendar page to call the JavaScript function draw_color_dot with the appropriate color codes for each date with three waste collections.

function draw_color_dot(idEl,color1,color2,color3){
	var c = document.getElementById(idEl);
	c.style.width ='100%';
	c.style.height='100%';
	//set the internal size to match the parent
	c.width  = c.offsetWidth;
	c.height = c.offsetHeight;
	var ctx = c.getContext("2d");
	var x=c.width/2;
	var y=c.width/2;
	var r=c.width/2;
	slice(ctx,x,y,r,30,120,color1);
	slice(ctx,x,y,r,150,120,color2);
	slice(ctx,x,y,r,270,120,color3);	
}

function rad(degrees){
	return Math.PI/180*degrees;
}

function slice(ctx,x,y,r,startDegr,lengthDegr,color){
	ctx.beginPath();
	ctx.strokeStyle = "transparent";
	ctx.moveTo(x, y);
	theta=rad(startDegr);
	ctx.lineTo(x + r * Math.cos(theta), y + r * Math.sin(theta));
	ctx.moveTo(x, y);
	theta=rad(startDegr+lengthDegr);
	ctx.lineTo(x + r * Math.cos(theta), y + r * Math.sin(theta));
	ctx.moveTo(x, y);
	ctx.arc(x, y, r, rad(startDegr),theta);
	ctx.fillStyle = color;
	ctx.fill();
	ctx.stroke();
}

The HTML code will look like this:


	
Désolé, votre navigateur ne prend pas en charge <canvas>.
24

Predicting the waste collection calendar for 2018

For the year 2017 the collection dates were extracted from an information leaflet and saved to the database. After analyzing the regularities it was relatively easy to design PHP code to predict all collection dates for 2018, thanks to the PHP classes DateInterval and DatePeriod The collection schedule changed considerably for 2018 but the application needed only some minor adaptation in the predicting patterns to reflect these changes. Saving the collection dates in the database was not necessary any more. The application will predict also all collecton dates for 2019 and after if there are no changes in the schedule.

The function weekday_pattern() returns an array with all dates on a certain weekday and conforming to a certain pattern as defined by several constants.

const WEEKLY=1;
const WEEK1AND3=2;//1st and 3th week of the month
const WEEK2AND4=3;//2nd and 4th week of the month
const LAST_IN_MONTH=4;
const SPECIAL_SACS=5;//weekly starting from april 2018, only 1st date in Dec. 
const EVEN_WEEKS=6; //1 time a week on even weeks during all year
const UNEVEN_WEEKS=7; //1 time a week on uneven weeks during all year
		
public static function weekday_pattern($weekday,$flag_pattern=5,$start='2017-01-01',$end='2018-01-01'){