summaryrefslogtreecommitdiff
path: root/app/Model
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-09-20 18:24:15 -0400
committerFrederic Guillot <fred@kanboard.net>2015-09-20 18:24:15 -0400
commite6f547abcfe684658a7498391db72d13b6aa7d9a (patch)
tree75b709c12fb03e11d7cb85558558f89f19abb284 /app/Model
parent2021dccc5a444f60c5ba1673d94b39999912cd26 (diff)
Move timetable to a plugin
Plugin repository: https://github.com/kanboard/plugin-timetable
Diffstat (limited to 'app/Model')
-rw-r--r--app/Model/SubtaskTimeTracking.php38
-rw-r--r--app/Model/Timetable.php356
-rw-r--r--app/Model/TimetableDay.php87
-rw-r--r--app/Model/TimetableExtra.php22
-rw-r--r--app/Model/TimetableOff.php125
-rw-r--r--app/Model/TimetableWeek.php91
6 files changed, 28 insertions, 691 deletions
diff --git a/app/Model/SubtaskTimeTracking.php b/app/Model/SubtaskTimeTracking.php
index 56998769..d65f2f75 100644
--- a/app/Model/SubtaskTimeTracking.php
+++ b/app/Model/SubtaskTimeTracking.php
@@ -150,13 +150,14 @@ class SubtaskTimeTracking extends Base
*
* @access public
* @param integer $user_id
- * @param integer $start
- * @param integer $end
+ * @param string $start ISO-8601 format
+ * @param string $end
* @return array
*/
public function getUserCalendarEvents($user_id, $start, $end)
{
- $result = $this->getUserQuery($user_id)
+ $hook = 'model:subtask-time-tracking:calendar:events';
+ $events = $this->getUserQuery($user_id)
->addCondition($this->getCalendarCondition(
$this->dateParser->getTimestampFromIsoFormat($start),
$this->dateParser->getTimestampFromIsoFormat($end),
@@ -165,9 +166,16 @@ class SubtaskTimeTracking extends Base
))
->findAll();
- $result = $this->timetable->calculateEventsIntersect($user_id, $result, $start, $end);
+ if ($this->hook->exists($hook)) {
+ $events = $this->hook->first($hook, array(
+ 'user_id' => $user_id,
+ 'events' => $events,
+ 'start' => $start,
+ 'end' => $end,
+ ));
+ }
- return $this->toCalendarEvents($result);
+ return $this->toCalendarEvents($events);
}
/**
@@ -293,6 +301,7 @@ class SubtaskTimeTracking extends Base
*/
public function getTimeSpent($subtask_id, $user_id)
{
+ $hook = 'model:subtask-time-tracking:calculate:time-spent';
$start_time = $this->db
->table(self::TABLE)
->eq('subtask_id', $subtask_id)
@@ -300,14 +309,23 @@ class SubtaskTimeTracking extends Base
->eq('end', 0)
->findOneColumn('start');
- if ($start_time) {
- $start = new DateTime;
- $start->setTimestamp($start_time);
+ if (empty($start_time)) {
+ return 0;
+ }
+
+ $end = new DateTime;
+ $start = new DateTime;
+ $start->setTimestamp($start_time);
- return $this->timetable->calculateEffectiveDuration($user_id, $start, new DateTime);
+ if ($this->hook->exists($hook)) {
+ return $this->hook->first($hook, array(
+ 'user_id' => $user_id,
+ 'start' => $start,
+ 'end' => $end,
+ ));
}
- return 0;
+ return $this->dateParser->getHours($start, $end);
}
/**
diff --git a/app/Model/Timetable.php b/app/Model/Timetable.php
deleted file mode 100644
index 6ddf826b..00000000
--- a/app/Model/Timetable.php
+++ /dev/null
@@ -1,356 +0,0 @@
-<?php
-
-namespace Model;
-
-use DateTime;
-use DateInterval;
-
-/**
- * Timetable
- *
- * @package model
- * @author Frederic Guillot
- */
-class Timetable extends Base
-{
- /**
- * User time slots
- *
- * @access private
- * @var array
- */
- private $day;
- private $week;
- private $overtime;
- private $timeoff;
-
- /**
- * Get a set of events by using the intersection between the timetable and the time tracking data
- *
- * @access public
- * @param integer $user_id
- * @param array $events Time tracking data
- * @param string $start ISO8601 date
- * @param string $end ISO8601 date
- * @return array
- */
- public function calculateEventsIntersect($user_id, array $events, $start, $end)
- {
- $start_dt = new DateTime($start);
- $start_dt->setTime(0, 0);
-
- $end_dt = new DateTime($end);
- $end_dt->setTime(23, 59);
-
- $timetable = $this->calculate($user_id, $start_dt, $end_dt);
-
- // The user has no timetable
- if (empty($this->week)) {
- return $events;
- }
-
- $results = array();
-
- foreach ($events as $event) {
- $results = array_merge($results, $this->calculateEventIntersect($event, $timetable));
- }
-
- return $results;
- }
-
- /**
- * Get a serie of events based on the timetable and the provided event
- *
- * @access public
- * @param array $event
- * @param array $timetable
- * @return array
- */
- public function calculateEventIntersect(array $event, array $timetable)
- {
- $events = array();
-
- foreach ($timetable as $slot) {
-
- $start_ts = $slot[0]->getTimestamp();
- $end_ts = $slot[1]->getTimestamp();
-
- if ($start_ts > $event['end']) {
- break;
- }
-
- if ($event['start'] <= $start_ts) {
- $event['start'] = $start_ts;
- }
-
- if ($event['start'] >= $start_ts && $event['start'] <= $end_ts) {
-
- if ($event['end'] >= $end_ts) {
- $events[] = array_merge($event, array('end' => $end_ts));
- }
- else {
- $events[] = $event;
- break;
- }
- }
- }
-
- return $events;
- }
-
- /**
- * Calculate effective worked hours by taking into consideration the timetable
- *
- * @access public
- * @param integer $user_id
- * @param \DateTime $start
- * @param \DateTime $end
- * @return float
- */
- public function calculateEffectiveDuration($user_id, DateTime $start, DateTime $end)
- {
- $end_timetable = clone($end);
- $end_timetable->setTime(23, 59);
-
- $timetable = $this->calculate($user_id, $start, $end_timetable);
- $found_start = false;
- $hours = 0;
-
- // The user has no timetable
- if (empty($this->week)) {
- return $this->dateParser->getHours($start, $end);
- }
-
- foreach ($timetable as $slot) {
-
- $isStartSlot = $this->dateParser->withinDateRange($start, $slot[0], $slot[1]);
- $isEndSlot = $this->dateParser->withinDateRange($end, $slot[0], $slot[1]);
-
- // Start and end are within the same time slot
- if ($isStartSlot && $isEndSlot) {
- return $this->dateParser->getHours($start, $end);
- }
-
- // We found the start slot
- if (! $found_start && $isStartSlot) {
- $found_start = true;
- $hours = $this->dateParser->getHours($start, $slot[1]);
- }
- else if ($found_start) {
-
- // We found the end slot
- if ($isEndSlot) {
- $hours += $this->dateParser->getHours($slot[0], $end);
- break;
- }
- else {
-
- // Sum hours of the intermediate time slots
- $hours += $this->dateParser->getHours($slot[0], $slot[1]);
- }
- }
- }
-
- // The start date was not found in regular hours so we get the nearest time slot
- if (! empty($timetable) && ! $found_start) {
- $slot = $this->findClosestTimeSlot($start, $timetable);
-
- if ($start < $slot[0]) {
- return $this->calculateEffectiveDuration($user_id, $slot[0], $end);
- }
- }
-
- return $hours;
- }
-
- /**
- * Find the nearest time slot
- *
- * @access public
- * @param DateTime $date
- * @param array $timetable
- * @return array
- */
- public function findClosestTimeSlot(DateTime $date, array $timetable)
- {
- $values = array();
-
- foreach ($timetable as $slot) {
- $t1 = abs($slot[0]->getTimestamp() - $date->getTimestamp());
- $t2 = abs($slot[1]->getTimestamp() - $date->getTimestamp());
-
- $values[] = min($t1, $t2);
- }
-
- asort($values);
- return $timetable[key($values)];
- }
-
- /**
- * Get the timetable for a user for a given date range
- *
- * @access public
- * @param integer $user_id
- * @param \DateTime $start
- * @param \DateTime $end
- * @return array
- */
- public function calculate($user_id, DateTime $start, DateTime $end)
- {
- $timetable = array();
-
- $this->day = $this->timetableDay->getByUser($user_id);
- $this->week = $this->timetableWeek->getByUser($user_id);
- $this->overtime = $this->timetableExtra->getByUserAndDate($user_id, $start->format('Y-m-d'), $end->format('Y-m-d'));
- $this->timeoff = $this->timetableOff->getByUserAndDate($user_id, $start->format('Y-m-d'), $end->format('Y-m-d'));
-
- for ($today = clone($start); $today <= $end; $today->add(new DateInterval('P1D'))) {
- $week_day = $today->format('N');
- $timetable = array_merge($timetable, $this->getWeekSlots($today, $week_day));
- $timetable = array_merge($timetable, $this->getOvertimeSlots($today, $week_day));
- }
-
- return $timetable;
- }
-
- /**
- * Return worked time slots for the given day
- *
- * @access public
- * @param \DateTime $today
- * @param string $week_day
- * @return array
- */
- public function getWeekSlots(DateTime $today, $week_day)
- {
- $slots = array();
- $dayoff = $this->getDayOff($today);
-
- if (! empty($dayoff) && $dayoff['all_day'] == 1) {
- return array();
- }
-
- foreach ($this->week as $slot) {
- if ($week_day == $slot['day']) {
- $slots = array_merge($slots, $this->getDayWorkSlots($slot, $dayoff, $today));
- }
- }
-
- return $slots;
- }
-
- /**
- * Get the overtime time slots for the given day
- *
- * @access public
- * @param \DateTime $today
- * @param string $week_day
- * @return array
- */
- public function getOvertimeSlots(DateTime $today, $week_day)
- {
- $slots = array();
-
- foreach ($this->overtime as $slot) {
-
- $day = new DateTime($slot['date']);
-
- if ($week_day == $day->format('N')) {
-
- if ($slot['all_day'] == 1) {
- $slots = array_merge($slots, $this->getDaySlots($today));
- }
- else {
- $slots[] = $this->getTimeSlot($slot, $day);
- }
- }
- }
-
- return $slots;
- }
-
- /**
- * Get worked time slots and remove time off
- *
- * @access public
- * @param array $slot
- * @param array $dayoff
- * @param \DateTime $today
- * @return array
- */
- public function getDayWorkSlots(array $slot, array $dayoff, DateTime $today)
- {
- $slots = array();
-
- if (! empty($dayoff) && $dayoff['start'] < $slot['end']) {
-
- if ($dayoff['start'] > $slot['start']) {
- $slots[] = $this->getTimeSlot(array('end' => $dayoff['start']) + $slot, $today);
- }
-
- if ($dayoff['end'] < $slot['end']) {
- $slots[] = $this->getTimeSlot(array('start' => $dayoff['end']) + $slot, $today);
- }
- }
- else {
- $slots[] = $this->getTimeSlot($slot, $today);
- }
-
- return $slots;
- }
-
- /**
- * Get regular day work time slots
- *
- * @access public
- * @param \DateTime $today
- * @return array
- */
- public function getDaySlots(DateTime $today)
- {
- $slots = array();
-
- foreach ($this->day as $day) {
- $slots[] = $this->getTimeSlot($day, $today);
- }
-
- return $slots;
- }
-
- /**
- * Get the start and end time slot for a given day
- *
- * @access public
- * @param array $slot
- * @param \DateTime $today
- * @return array
- */
- public function getTimeSlot(array $slot, DateTime $today)
- {
- $date = $today->format('Y-m-d');
-
- return array(
- new DateTime($date.' '.$slot['start']),
- new DateTime($date.' '.$slot['end']),
- );
- }
-
- /**
- * Return day off time slot
- *
- * @access public
- * @param \DateTime $today
- * @return array
- */
- public function getDayOff(DateTime $today)
- {
- foreach ($this->timeoff as $day) {
-
- if ($day['date'] === $today->format('Y-m-d')) {
- return $day;
- }
- }
-
- return array();
- }
-}
diff --git a/app/Model/TimetableDay.php b/app/Model/TimetableDay.php
deleted file mode 100644
index 0c7bf20b..00000000
--- a/app/Model/TimetableDay.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-namespace Model;
-
-use SimpleValidator\Validator;
-use SimpleValidator\Validators;
-
-/**
- * Timetable Workweek
- *
- * @package model
- * @author Frederic Guillot
- */
-class TimetableDay extends Base
-{
- /**
- * SQL table name
- *
- * @var string
- */
- const TABLE = 'timetable_day';
-
- /**
- * Get the timetable for a given user
- *
- * @access public
- * @param integer $user_id User id
- * @return array
- */
- public function getByUser($user_id)
- {
- return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('start')->findAll();
- }
-
- /**
- * Add a new time slot in the database
- *
- * @access public
- * @param integer $user_id User id
- * @param string $start Start hour (24h format)
- * @param string $end End hour (24h format)
- * @return boolean|integer
- */
- public function create($user_id, $start, $end)
- {
- $values = array(
- 'user_id' => $user_id,
- 'start' => $start,
- 'end' => $end,
- );
-
- return $this->persist(self::TABLE, $values);
- }
-
- /**
- * Remove a specific time slot
- *
- * @access public
- * @param integer $slot_id
- * @return boolean
- */
- public function remove($slot_id)
- {
- return $this->db->table(self::TABLE)->eq('id', $slot_id)->remove();
- }
-
- /**
- * Validate creation
- *
- * @access public
- * @param array $values Form values
- * @return array $valid, $errors [0] = Success or not, [1] = List of errors
- */
- public function validateCreation(array $values)
- {
- $v = new Validator($values, array(
- new Validators\Required('user_id', t('Field required')),
- new Validators\Required('start', t('Field required')),
- new Validators\Required('end', t('Field required')),
- ));
-
- return array(
- $v->execute(),
- $v->getErrors()
- );
- }
-}
diff --git a/app/Model/TimetableExtra.php b/app/Model/TimetableExtra.php
deleted file mode 100644
index 48db662d..00000000
--- a/app/Model/TimetableExtra.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-namespace Model;
-
-use SimpleValidator\Validator;
-use SimpleValidator\Validators;
-
-/**
- * Timetable over-time
- *
- * @package model
- * @author Frederic Guillot
- */
-class TimetableExtra extends TimetableOff
-{
- /**
- * SQL table name
- *
- * @var string
- */
- const TABLE = 'timetable_extra';
-}
diff --git a/app/Model/TimetableOff.php b/app/Model/TimetableOff.php
deleted file mode 100644
index e4fe32d2..00000000
--- a/app/Model/TimetableOff.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-
-namespace Model;
-
-use SimpleValidator\Validator;
-use SimpleValidator\Validators;
-
-/**
- * Timetable time off
- *
- * @package model
- * @author Frederic Guillot
- */
-class TimetableOff extends Base
-{
- /**
- * SQL table name
- *
- * @var string
- */
- const TABLE = 'timetable_off';
-
- /**
- * Get query to fetch everything (pagination)
- *
- * @access public
- * @param integer $user_id User id
- * @return \PicoDb\Table
- */
- public function getUserQuery($user_id)
- {
- return $this->db->table(static::TABLE)->eq('user_id', $user_id);
- }
-
- /**
- * Get the timetable for a given user
- *
- * @access public
- * @param integer $user_id User id
- * @return array
- */
- public function getByUser($user_id)
- {
- return $this->db->table(static::TABLE)->eq('user_id', $user_id)->desc('date')->asc('start')->findAll();
- }
-
- /**
- * Get the timetable for a given user
- *
- * @access public
- * @param integer $user_id User id
- * @param string $start_date
- * @param string $end_date
- * @return array
- */
- public function getByUserAndDate($user_id, $start_date, $end_date)
- {
- return $this->db->table(static::TABLE)
- ->eq('user_id', $user_id)
- ->gte('date', $start_date)
- ->lte('date', $end_date)
- ->desc('date')
- ->asc('start')
- ->findAll();
- }
-
- /**
- * Add a new time slot in the database
- *
- * @access public
- * @param integer $user_id User id
- * @param string $date Day (ISO8601 format)
- * @param boolean $all_day All day flag
- * @param float $start Start hour (24h format)
- * @param float $end End hour (24h format)
- * @param string $comment
- * @return boolean|integer
- */
- public function create($user_id, $date, $all_day, $start = '', $end = '', $comment = '')
- {
- $values = array(
- 'user_id' => $user_id,
- 'date' => $date,
- 'all_day' => (int) $all_day, // Postgres fix
- 'start' => $all_day ? '' : $start,
- 'end' => $all_day ? '' : $end,
- 'comment' => $comment,
- );
-
- return $this->persist(static::TABLE, $values);
- }
-
- /**
- * Remove a specific time slot
- *
- * @access public
- * @param integer $slot_id
- * @return boolean
- */
- public function remove($slot_id)
- {
- return $this->db->table(static::TABLE)->eq('id', $slot_id)->remove();
- }
-
- /**
- * Validate creation
- *
- * @access public
- * @param array $values Form values
- * @return array $valid, $errors [0] = Success or not, [1] = List of errors
- */
- public function validateCreation(array $values)
- {
- $v = new Validator($values, array(
- new Validators\Required('user_id', t('Field required')),
- new Validators\Required('date', t('Field required')),
- new Validators\Numeric('all_day', t('This value must be numeric')),
- ));
-
- return array(
- $v->execute(),
- $v->getErrors()
- );
- }
-}
diff --git a/app/Model/TimetableWeek.php b/app/Model/TimetableWeek.php
deleted file mode 100644
index b22b3b7e..00000000
--- a/app/Model/TimetableWeek.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-namespace Model;
-
-use SimpleValidator\Validator;
-use SimpleValidator\Validators;
-
-/**
- * Timetable Workweek
- *
- * @package model
- * @author Frederic Guillot
- */
-class TimetableWeek extends Base
-{
- /**
- * SQL table name
- *
- * @var string
- */
- const TABLE = 'timetable_week';
-
- /**
- * Get the timetable for a given user
- *
- * @access public
- * @param integer $user_id User id
- * @return array
- */
- public function getByUser($user_id)
- {
- return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('day')->asc('start')->findAll();
- }
-
- /**
- * Add a new time slot in the database
- *
- * @access public
- * @param integer $user_id User id
- * @param string $day Day of the week (ISO-8601)
- * @param string $start Start hour (24h format)
- * @param string $end End hour (24h format)
- * @return boolean|integer
- */
- public function create($user_id, $day, $start, $end)
- {
- $values = array(
- 'user_id' => $user_id,
- 'day' => $day,
- 'start' => $start,
- 'end' => $end,
- );
-
- return $this->persist(self::TABLE, $values);
- }
-
- /**
- * Remove a specific time slot
- *
- * @access public
- * @param integer $slot_id
- * @return boolean
- */
- public function remove($slot_id)
- {
- return $this->db->table(self::TABLE)->eq('id', $slot_id)->remove();
- }
-
- /**
- * Validate creation
- *
- * @access public
- * @param array $values Form values
- * @return array $valid, $errors [0] = Success or not, [1] = List of errors
- */
- public function validateCreation(array $values)
- {
- $v = new Validator($values, array(
- new Validators\Required('user_id', t('Field required')),
- new Validators\Required('day', t('Field required')),
- new Validators\Numeric('day', t('This value must be numeric')),
- new Validators\Required('start', t('Field required')),
- new Validators\Required('end', t('Field required')),
- ));
-
- return array(
- $v->execute(),
- $v->getErrors()
- );
- }
-}