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
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.">
Suggested location(s):
/interface_{custom}/main/intranet_home.html
or
/interface_{custom}/main/right_column.html
Discussion