Translations of this page:

Anniversary reminder

This component is designed to display upcoming anniversary events with a time-frame of upto 1 year away from today. The component will display the names of the users as long as how many days away from today the event is. The length of the names can be given a maximum, enabling the component to be implemented within sidebars.

This article will explain how to show the anniversary component.

1. navigate into the folder intranet/common/classes

2. Create the file “TemplaterComponentAnniversary.php” (keep in mind if you’re using a linux system, the name is case-sensetive), and place in it the following:

<?php
/**
 * A component that is designed to show up and coming anniversary events
 *
 * @author Daniel Munn [daniel.munn@claromentis.com]
 */
 
require_once("../common/metadata_pkg.php");
 
class TemplaterComponentAnniversary implements TemplaterComponent
{
	const DEFAULT_UNIT_QUANTITY = 7; // Default is 7 days;
	const DEFAULT_MAX_RENDER = -1; // Render them all!
	protected $data; // Data storage
	protected $html; //Rendering information
	protected $lasterror; //Output information;
	
	protected $metakey; //Metadata Key
	protected $displaymax; // Records to display;
	protected $datemax; //Maximum date we're checking against
	protected $datemin; //Today's date
	protected $private = false; // Privacy flag
	
	/**
	 * Class constuctor
	 */
	public function __construct() 
	{
		//With the constructor, we just ensure dates are pre-filled
		$this->datemax = new DateDay();
		$this->datemin = new DateDay();
	}
 
	/**
	 * Attribute array values:
	 *		* metakey (str) - Metadata key to bind source to
	 *		* display (int) - [Optional - default infinite for time period specified] Number of anniversary events to render
	 *		* timeframe (day/week/month) - [Optional - default day]Unit by which to retrieve information window
	 *		* noevents (str) - [Optional] Message to show if there are no events
	 *		* private (bool) - [Optional] Flag to only show this persons events as opposed to everyones
	 */
	public function Show($attributes) 
	{
		global $db;
		
		//Check Metakey Information
		if (!$this->CheckMetadata(&$attributes))
			return $this->lasterror; //Output error, and hold execution
		
		//Attribute: Display - this will control how many birthdays are shown
		$this->CheckDisplay(&$attributes);
		
		//Attribute: CheckPrivacy - this will control how the component renders (to individual, or to everyone)
		$this->CheckPrivacy(&$attributes);
		
		//Attribute: Timeframe - this will control how far forward (in time) this component will scope
		$this->CheckTimeFrame(&$attributes);
 
		 // Process metadata information including date processing - this passes information to Data;
		$this->ProcessMetadata();
		
		//This is a continuation from the above method, we process the data into a html format
		$this->ProcessData();
		
		//Return html processed by ProcessData;
		return $this->html;
	}
 
	/**
	 * Check and store information from the attribute: "metakey"
	 * @param array $attributes - Pointer to attributes array;
	 */
	protected function CheckMetadata (&$attributes) 
	{
		global $g_meta_field_factory;	
		if (isset($attributes['metakey']))  //Do we have metakey info?
		{
			$dmfpobj = $g_meta_field_factory->GetPrototypeByKey($attributes['metakey']);
			if (!$dmfpobj) //If object isnt instantiated loading failed and thus key does not exist
			{
				$this->lasterror = $g_meta_field_factory->GetErrMsg();
				return false;
			}
			if ($dmfpobj->IsRepeatable())
			{
       			$this->lasterror = "The Metadata specified is marked as repeatable, which is wrong.";
       			return false;
			}
			switch ($dmfpobj->GetMetaType()) 
			{
				case META_TYPE_DATE:
					$this->metakey = $attributes['metakey'];
					unset($dmfpobj);
					return true;
				case META_TYPE_DATETIME:
					$this->lasterror = "The Metadata specified is set to date-time, this needs to be set to date.";
					return false;
				default:
					$this->lasterror = "The Metadata specified is currently set to an un-usable data format.";
					return false;
			}
		} 
		else
		{
			$this->lasterror = "No Metadata key was specified.";
			return false; // Not successful
		}
	}
	
	/**
	 * Check and store information from the attribute: "display"
	 * 
	 * @param array $attributes - Pointer to attributes array;
	 */
	protected function CheckDisplay (&$attributes) 
	{
		$this->displaymax = self::DEFAULT_MAX_RENDER;
		if (isset($attributes['display'])) 
		{
			if (is_numeric($attributes['display'])) 
			{
				if ($attributes['display'] > 0) 
				{
					$this->displaymax = $attributes['display']; //We have a valid positive integer, we commit that to maxrender
				}
			}
		}
	}
	
	/**
	 * CheckPriavacy - checks and processes privacy settings based on input from component
	 * 
	 * @param array $attributes - Pointer to attributes array;
	 */
	protected function CheckPrivacy(&$attributes)
	{
		if (isset($attributes['private']))
		{
			if ( strtolower(trim($attributes['private'])) == 'true' )
			{
				$this->private = true; // Flag privacy
			}
		}
	}
	
	/**
	 * CheckTimeframe - checks and processes timeframe input from component
	 * 
	 * @param array $attributes - Pointer to attributes array;
	 */
	protected function CheckTimeframe (&$attributes)
	{
		if(isset($attributes['timeframe'])) 
		{
			@$this->datemax->modify('+'.$attributes['timeframe']);
			if(!$this->datemax->after($this->datemin))
				$this->datemax->modify('+'.self::DEFAULT_UNIT_QUANTITY.' days');
		}
		else
		{
			$this->datemax->modify('+'.self::DEFAULT_UNIT_QUANTITY.' days');
		}
	}
	
	/**
	 * CheckDate - processes dates inbound so that they can be made relative to current year
	 * 
	 * @param int $dateinput - eight character integer format of date
	 */
	protected function CheckDate ($dateinput)
	{
		$datetmp = new DateDay($dateinput);
		$datetmp->SetYear($this->datemin->GetYear());
		if ($datetmp->before($this->datemin)) //It is still before today with this year on it, add another year for comparison 
			$datetmp->modify('+1 year');
		return $datetmp;
	}
 
	/**
	 * ProcessMetadata - Recurse through stored information and places information in temporary data storage
	 */
	protected function ProcessMetadata() {
		global $db;
		
		//Adjust query based on next variable
		$qp = new QueryPart('');
		if ( $this->private )
		{
			$qp = new QueryPart('AND u.id = ' . $_SESSION['SESSION_UID']);
		}		
		$query = new Query("SELECT u.id, u.firstname, u.surname, m.intval FROM users u, metadata_simple m WHERE m.name eq:str:META_KEY AND m.aggregation = int:AGG_USER AND m.intval > 0 " . $qp->AsPart(), $this->metakey, AGGREGATION_USER);
		$query->addJoinCondition('u', 'm', 'u.id=m.object_id');
		
		$result = $db->query($query);
		
		//Due to the fact it will only check before or after and not an equals condition - we need to substract one from datemin and add one to datemax
		$this->datemin->modify('-1 day');
		$this->datemax->modify('+1 day');
		
		while ($row = $result->fetchArray()) 
		{
			//We have to take the date of their birthday and affix this year to it;
			//Parse date with this year.
 
			$row['intval'] = $this->CheckDate($row['intval']);
			if ($row['intval']->after($this->datemin) && $row['intval']->before($this->datemax))
			{
				//Now we calculate everything into a date
				$datecalc = $row['intval']->toDays() - $this->datemin->toDays() -1; //We subtract an extra one to take into account we deducted one from the range, so we need to match the shift we've created
				//$datecalc now hold the number of days between dates;
				$this->data[$datecalc][] = $row;
			}
		}
	}
 
	/**
	 * ProcessData - Take information from temporary data store and render into an output format 
	 */
	
	protected function ProcessData() {
		$this->html .= "<ul>";
		
		if( count($this->data) > 0 )
		{
			ksort($this->data); //Lets order our array properly
			$rendered = 0; // Count the number that have been processed
			foreach ($this->data as $daynumber => $dayarray) //Cycle through array of data breaking into days and relevent array
			{
				if ($rendered >= $this->displaymax && $this->displaymax > 0)
					break; // Break out if we've reached max rendered 
				foreach ($dayarray as $dayevent) //Break down array of events for specified day
				{
					//Now, we have broken information into a specific event; this is a rendering aspect of this loop
					if ($rendered >= $this->displaymax && $this->displaymax > 0)
						break; // Break out if we've reached max rendered 
					$this->html .= '<li>';
					//At the moment, we're going to highlight anything thats a week or under;
					if ($daynumber <= 7) 
						$this->html .= '<strong>';
					$this->html .= sprintf('<a href="/intranet/people/viewprofile.php?id=%d">%s</a> (%d %s)', $dayevent['id'], name_display($dayevent['firstname'], $dayevent['surname']), $daynumber, "day" . (($daynumber > 0) ? 's' : ''));
					$rendered++; //Beancounting for maxrender
					//Close the above week rendering
					if ($daynumber <= 7) 
						$this->html .= '</strong>';
					$this->html .= '</li>';
				}
			}
		}
		else
		{
			$this->html .= '<li>';
			if (strlen($attributes['noevents']) > 0)
			{
				$this->html .= htmlentities($attributes['noevents']);
			}
			else
			{
				$this->html .= 'No upcoming events';
			}
			$this->html .= "</li>";
		}
		$this->html .= "</ul>";
	}
 }
 ?>

Once completed, its time to configure this component: Firstly we’ll start by creating a user metadata information field

  • Login and go to your administration panel
  • Click the Metadata button
  • Select the Edit button, next to Users, in the Misc metadata region this component only works with user metadata

  • On the page that appears, select “Create new field”
  • In this instance we’re going to create a metadata field that holds the date of birth:
    • Ensure that you remember the Key (you’ll need it later)
    • Change the type to “Date” (not to be confused with DateTime)
    • DO NOT select repeatable
  • Click save once your done; its now time to edit the template.

3. Paste the following component code anywhere on a templater file

<component class="TemplaterComponentAnniversary" display="10" timeframe="2 weeks" metakey="dob" noevent="There are no upcoming events.">
  • display - This is an optional field which controls the number of events shown, if omitted it will show every event in the specified timeframe.
  • timeframe - How far in the future would you like for this to provide events for? eg: 1 week, 3 months etc; this will only support upto 1 year; if omitted, it will default to 1 week.
  • metakey - Above when setting up your metadata field, I said to make sure you remember the key - type your key into this value. This parameter is not option
  • noevent - An optional input that specifies a message to show when there are no events in the timeframe specified.
  • private - An optional input that specifies privacy; if set to “true” only events for the logged in user are shown, if not set it will show anniversary information for every user (eg: as a component to show birthdays).

Suggested location(s):

/interface_{custom}/main/intranet_home.html  

or

/interface_{custom}/main/right_column.html
 
components/anniversary.txt · Last modified: 07/06/2011 10:49 by sweta
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki