/**
  * Returns current age or at a given date when supplied
  *
  * @param \MUtil_Date|null $date
  * @return int
  */
 public function getAge($date = NULL)
 {
     if (is_null($date)) {
         $date = new \MUtil_Date();
     }
     if ($date instanceof \MUtil_Date) {
         // Now calculate age
         $birthDate = $this->getBirthDate();
         if ($birthDate instanceof \Zend_Date) {
             $age = $date->get('Y') - $birthDate->get('Y');
             if ($date->get('MMdd') < $birthDate->get('MMdd')) {
                 $age--;
             }
         } else {
             return;
         }
     }
     return $age;
 }
 /**
  * Creates the base model.
  *
  * @return \MUtil_Model_SelectModel
  */
 protected function createModel()
 {
     $groupby['period_1'] = new \Zend_Db_Expr("YEAR({$this->dateFrom})");
     $date = new \MUtil_Date();
     switch ($this->dateType) {
         case 'D':
             $keyCount = 1;
             $groupby['period_1'] = new \Zend_Db_Expr("CONVERT({$this->dateFrom}, DATE)");
             $date->setTime(0);
             $date->addDay($this->dateFactor - $this->dateRange);
             $start = $date->getIso();
             for ($i = -$this->dateRange; $i <= $this->dateRange; $i++) {
                 if (0 == $i) {
                     $this->dateCurrentStart = clone $date;
                     $this->dateCurrentEnd = clone $date;
                     $this->dateCurrentEnd->setTimeToDayEnd();
                 }
                 $values = array();
                 $values['period_1'] = $date->get('yyyy-MM-dd');
                 $values['range'] = $i;
                 $requiredRows[$i] = $values;
                 $date->addDay(1);
             }
             $date->subSecond(1);
             $end = $date->getIso();
             break;
         case 'W':
             $keyCount = 2;
             // Use MONDAY as start of week
             $groupby['period_1'] = new \Zend_Db_Expr("substr(YEARWEEK(gto_valid_from, 3),1,4)");
             //$groupby['period_1'] = new \Zend_Db_Expr("YEAR($this->dateFrom) - CASE WHEN WEEK($this->dateFrom, 1) = 0 THEN 1 ELSE 0 END");
             $groupby['period_2'] = new \Zend_Db_Expr("WEEK({$this->dateFrom}, 3)");
             $date->setWeekday(1);
             $date->setTime(0);
             $date->addWeek($this->dateFactor - $this->dateRange);
             $start = $date->getIso();
             for ($i = -$this->dateRange; $i <= $this->dateRange; $i++) {
                 if (0 == $i) {
                     $this->dateCurrentStart = clone $date;
                     $this->dateCurrentEnd = clone $date;
                     $this->dateCurrentEnd->addWeek(1)->subSecond(1);
                 }
                 $values = array();
                 $values['period_1'] = $date->get(\Zend_Date::YEAR);
                 $values['period_2'] = $date->get(\Zend_Date::WEEK);
                 // When monday is in the previous year, add one to the year
                 if ($date->get(\Zend_Date::DAY_OF_YEAR) > 14 && $date->get(\Zend_Date::WEEK) == 1) {
                     $values['period_1'] = $values['period_1'] + 1;
                 }
                 $values['range'] = $i;
                 $requiredRows[$i] = $values;
                 $date->addWeek(1);
             }
             $date->subSecond(1);
             $end = $date->getIso();
             break;
         case 'M':
             $keyCount = 2;
             $groupby['period_2'] = new \Zend_Db_Expr("MONTH({$this->dateFrom})");
             $date->setDay(1);
             $date->setTime(0);
             $date->addMonth($this->dateFactor - $this->dateRange);
             $start = $date->getIso();
             for ($i = -$this->dateRange; $i <= $this->dateRange; $i++) {
                 if (0 == $i) {
                     $this->dateCurrentStart = clone $date;
                     $this->dateCurrentEnd = clone $date;
                     $this->dateCurrentEnd->addMonth(1)->subSecond(1);
                 }
                 $values = array();
                 $values['period_1'] = $date->get(\Zend_Date::YEAR);
                 $values['period_2'] = $date->get(\Zend_Date::MONTH);
                 $values['range'] = $i;
                 $requiredRows[$i] = $values;
                 $date->addMonth(1);
             }
             $date->subSecond(1);
             $end = $date->getIso();
             break;
         case 'Y':
             $keyCount = 1;
             $date->setDay(1);
             $date->setMonth(1);
             $date->setTime(0);
             $date->addYear($this->dateFactor - $this->dateRange);
             $start = $date->getIso();
             for ($i = -$this->dateRange; $i <= $this->dateRange; $i++) {
                 if (0 == $i) {
                     $this->dateCurrentStart = clone $date;
                     $this->dateCurrentEnd = clone $date;
                     $this->dateCurrentEnd->addYear(1)->subSecond(1);
                 }
                 $values = array();
                 $values['period_1'] = $date->get(\Zend_Date::YEAR);
                 $values['range'] = $i;
                 $requiredRows[$i] = $values;
                 $date->addYear(1);
             }
             $date->subSecond(1);
             $end = $date->getIso();
             break;
         default:
             throw new \Gems_Exception_Coding('Incorrect date_type value: ' . $this->dateType);
     }
     $where = "{$this->dateFrom} BETWEEN '{$start}' AND '{$end}'";
     for ($i = -$this->dateRange; $i <= $this->dateRange; $i++) {
         $requiredRows[$i]['date_factor'] = $this->dateFactor + $i;
         $requiredRows[$i]['df_link'] = null;
         $requiredRows[$i]['df_label'] = null;
     }
     if ($this->dateRange > 0) {
         $requiredRows[-$this->dateRange]['df_link'] = $this->dateFactor - $this->dateRange * 2;
         $requiredRows[-$this->dateRange]['df_label'] = $this->_('<<');
         $requiredRows[$this->dateRange]['df_link'] = $this->dateFactor + $this->dateRange * 2;
         $requiredRows[$this->dateRange]['df_label'] = $this->_('>>');
         if ($this->dateRange > 1) {
             $i = intval($this->dateRange / 2);
             $requiredRows[-$i]['df_link'] = $this->dateFactor - 1;
             $requiredRows[-$i]['df_label'] = $this->_('<');
             $requiredRows[$i]['df_link'] = $this->dateFactor + 1;
             $requiredRows[$i]['df_label'] = $this->_('>');
         }
         $requiredRows[0]['df_link'] = $this->dateFactor ? '0' : null;
         $requiredRows[0]['df_label'] = $this->_('Now!');
     }
     if ($this->dateFactor) {
         $today = new \MUtil_Date();
         $this->dateFactorChanges['D'] = $this->dateCurrentStart->diffDays($today);
         $this->dateFactorChanges['W'] = $this->dateCurrentStart->diffWeeks($today);
         $this->dateFactorChanges['M'] = $this->dateCurrentStart->diffMonths($today);
         $this->dateFactorChanges['Y'] = $this->dateCurrentStart->diffYears($today);
     } else {
         $this->dateFactorChanges = array_fill_keys(array('D', 'W', 'M', 'Y'), 0);
     }
     // \MUtil_Echo::track($requiredRows);
     // \MUtil_Echo::rs($start, $end, $where);
     $select = new \Zend_Db_Select($this->db);
     $select->from($this->dataTableName, $groupby + $this->getDbFields());
     $select->where($where);
     $select->group($groupby);
     $this->processSelect($select);
     // \MUtil_Echo::r((string) $select);
     $model = new \MUtil_Model_SelectModel($select, $this->dataTableName);
     // Display by column cannot use formatFunction as it is a simple repeater
     // $model->set('duration_avg', 'formatFunction', $this->util->getLocalized()->formatNumber);
     $transformer = new \MUtil_Model_Transform_RequiredRowsTransformer();
     $transformer->setDefaultRow($this->getDefaultRow());
     $transformer->setRequiredRows($requiredRows);
     $transformer->setKeyItemCount($keyCount);
     $model->addTransformer($transformer);
     return $model;
 }
 public function getHtmlOutput(\Zend_View_Abstract $view)
 {
     $this->_initView($view);
     $main = $this->creator->div(array('class' => 'panel panel-default', 'id' => 'trackwrapper', 'renderClosingTag' => true));
     $main->div(array('id' => 'modalpopup', 'renderClosingTag' => true));
     $model = $this->getModel();
     $model->trackUsage();
     $items = array('gto_id_respondent_track', 'gto_valid_from', 'gto_valid_until', 'gr2t_start_date', 'gtr_track_name', 'gr2t_track_info', 'gto_id_token', 'gto_round_description', 'forgroup', 'gsu_survey_name', 'gto_completion_time', 'gr2o_patient_nr', 'gr2o_id_organization', 'gro_icon_file', 'gto_icon_file');
     foreach ($items as $item) {
         $model->get($item);
     }
     $data = $model->load(true, $this->_fixedSort);
     $lastDate = null;
     $lastDescription = null;
     $doelgroep = null;
     $now = new \MUtil_Date();
     $today = $now->get($this->_dateFormat);
     $progressDiv = null;
     $respTrackId = 0;
     $trackProgress = null;
     $currentOrg = $this->loader->getCurrentUser()->getCurrentOrganizationId();
     $allowedOrgs = $this->loader->getCurrentUser()->getAllowedOrganizations();
     // The normal loop
     foreach ($data as $row) {
         if ($respTrackId !== $row['gto_id_respondent_track']) {
             if (isset($day) && new \MUtil_Date($lastDate, 'dd-MM-y') < $now) {
                 $day->class .= ' today';
                 unset($day);
             }
             $progressDiv = $this->finishGroup($progressDiv);
             $this->finishTrack($trackProgress);
             $lastDate = null;
             $doelgroep = null;
             $lastDescription = null;
             //if ($respTrackId == 0) {
             //    $track = $main->div(array('class' => 'panel panel-default traject active'));
             //} else {
             $track = $main->div(array('class' => 'panel panel-default traject'));
             //}
             $respTrackId = $row['gto_id_respondent_track'];
             $trackHeading = $track->div(array('class' => 'panel-heading', 'renderClosingTag' => true));
             $trackHeader = $trackHeading->h3(array('class' => "panel-title", 'renderClosingTag' => true));
             $trackParameterSource = array('gr2t_id_respondent_track' => $row['gto_id_respondent_track'], 'gr2o_patient_nr' => $row['gr2o_patient_nr'], 'gr2o_id_organization' => $row['gr2o_id_organization'], 'can_edit' => 1);
             if (array_key_exists($row['gr2o_id_organization'], $allowedOrgs) && $this->_trackEdit) {
                 $editLink = \MUtil_Html::create('i', array('class' => 'fa fa-pencil', 'renderClosingTag' => true, 'data-toggle' => 'tooltip', 'data-placement' => 'right', 'title' => $this->_("Edit track")));
                 $link = $this->createMenuLink($trackParameterSource, 'track', 'edit-track', $editLink, $this->_trackEdit);
                 $link->setAttrib('onClick', 'event.cancelBubble = true;');
             } else {
                 // When org not allowed, dont add the link, so the track will just open
                 $link = \MUtil_Html::create('span', array('class' => 'fa fa-pencil', 'renderClosingTag' => true));
             }
             $trackHeader[] = $link;
             $title = \MUtil_Html::create('span', array('class' => 'title'));
             $title[] = ' ' . $row['gtr_track_name'];
             $title[] = \MUtil_Html::create('span', array('class' => "fa fa-chevron-down fa-fw", 'renderClosingTag' => true));
             $trackHeader[] = $title;
             $deleteTrackContainer = \MUtil_Html::create('div', array('class' => 'otherOrg pull-right', 'renderClosingTag' => true));
             if ($row['gr2o_id_organization'] != $currentOrg) {
                 $org = $this->loader->getOrganization($row['gr2o_id_organization'])->getName();
                 $deleteTrackContainer[] = $org . ' ';
             }
             if (array_key_exists($row['gr2o_id_organization'], $allowedOrgs) && $this->_trackDelete) {
                 $deleteLink = \MUtil_Html::create('i', array('class' => 'fa fa-trash deleteIcon', 'renderClosingTag' => true, 'data-toggle' => 'tooltip', 'data-placement' => 'left', 'title' => $this->_("Delete track")));
                 $link = $this->createMenuLink($trackParameterSource, 'track', 'delete-track', $deleteLink, $this->_trackDelete)->setAttrib('onClick', 'event.cancelBubble = true;');
                 $deleteTrackContainer[] = $link;
             }
             $trackHeader[] = $deleteTrackContainer;
             if ($row['gr2t_start_date'] instanceof Zend_Date) {
                 $trackStartDate = $row['gr2t_start_date']->get($this->_dateFormat);
             } else {
                 $trackStartDate = $this->_('n/a');
             }
             $trackHeading->div($row['gr2t_track_info'], array('renderClosingTag' => true));
             $trackHeading->div($this->_('Start date') . ': ' . $trackStartDate, array('renderClosingTag' => true));
             $trackProgress = $trackHeading->div(array('class' => 'progress pull-right', 'renderClosingTag' => true));
             $container = $track->div(array('class' => 'panel-body', 'renderClosingTag' => true));
             $subcontainer = $container->div(array('class' => 'objecten', 'renderClosingTag' => true));
         }
         $date = $row['gto_valid_from'];
         if ($date instanceof \Zend_Date) {
             $date = $date->get($this->_dateFormat);
         } else {
             continue;
         }
         $description = $row['gto_round_description'];
         if ($lastDescription !== $description || !isset($day)) {
             $last = new \MUtil_Date($lastDate, 'dd-MM-y');
             if (isset($day) && $last < $now && $row['gto_valid_from'] > $now) {
                 $day->class .= ' today';
             }
             $lastDescription = $description;
             $progressDiv = $this->finishGroup($progressDiv);
             $lastDate = $date;
             $class = 'object';
             if ($date == $today) {
                 $class .= ' today';
             }
             $day = $subcontainer->div(array('class' => $class, 'renderClosingTag' => true));
             $day->h4(ucfirst($row['gto_round_description']));
             $day->h5($date);
             $doelgroep = null;
         } elseif (isset($day) && $lastDate !== $date) {
             // When we have a new start date, add the date and start a new group
             $day->h5($date);
             $lastDate = $date;
             $doelgroep = null;
         }
         if ($doelgroep !== $row['forgroup']) {
             $progressDiv = $this->finishGroup($progressDiv);
             $doelgroep = $row['forgroup'];
             $doelgroepDiv = $day->div(array('class' => 'actor', 'renderClosingTag' => true));
             //$progressDiv  = $doelgroepDiv->div(array('class' => 'progress'));
             $minIcon = \MUtil_Html::create('span', array('class' => 'fa fa-plus-square', 'renderClosingTag' => true));
             $title = $doelgroepDiv->h5(array($minIcon, $doelgroep));
             $progressDiv = $doelgroepDiv->div(array('class' => 'zplegenda', 'renderClosingTag' => true));
             $tokenDiv = $doelgroepDiv->div(array('class' => 'zpitems', 'renderClosingTag' => true));
         }
         $tokenDiv[] = $this->addToken($row);
     }
     if (isset($day) && new \MUtil_Date($lastDate, 'dd-MM-y') < $now) {
         $day->class .= ' today';
     }
     $progressDiv = $this->finishGroup($progressDiv);
     $this->finishTrack($trackProgress);
     return $main;
 }