Emmanuel BENOîT
1423434dfd
The amount of unsatisfied transitive dependencies is displayed in the tasks list (and used to sort it) and on task pages.
239 lines
6.9 KiB
PHP
239 lines
6.9 KiB
PHP
<?php
|
|
|
|
class DAO_Tasks
|
|
extends DAO
|
|
{
|
|
private static $priorities = array(
|
|
'1' => 'Lowest' ,
|
|
'2' => 'Low' ,
|
|
'3' => 'Normal' ,
|
|
'4' => 'High' ,
|
|
'5' => 'Very high' ,
|
|
);
|
|
|
|
|
|
public function translatePriority( $value )
|
|
{
|
|
return DAO_Tasks::$priorities[ "$value" ];
|
|
}
|
|
|
|
|
|
public function getAllTasks( )
|
|
{
|
|
return $this->query(
|
|
'SELECT * FROM tasks_list '
|
|
. 'ORDER BY ( CASE '
|
|
. 'WHEN completed_at IS NULL THEN '
|
|
. 'priority '
|
|
. 'ELSE '
|
|
. '-1 '
|
|
. 'END ) DESC , total_missing_dependencies ASC NULLS FIRST , added_at DESC' )->execute( );
|
|
}
|
|
|
|
public function getAllActiveTasks( )
|
|
{
|
|
return $this->query(
|
|
'SELECT * FROM tasks_list '
|
|
. 'WHERE completed_at IS NULL AND missing_dependencies IS NULL '
|
|
. 'ORDER BY priority DESC , added_at DESC' )->execute( );
|
|
}
|
|
|
|
public function getAllBlockedTasks( )
|
|
{
|
|
return $this->query(
|
|
'SELECT * FROM tasks_list '
|
|
. 'WHERE completed_at IS NULL AND missing_dependencies IS NOT NULL '
|
|
. 'ORDER BY priority DESC , total_missing_dependencies ASC , added_at DESC' )->execute( );
|
|
}
|
|
|
|
|
|
public function getTasksAt( Data_Item $item )
|
|
{
|
|
return $this->query(
|
|
'SELECT * FROM tasks_list '
|
|
. 'WHERE item = $1 '
|
|
. 'ORDER BY ( CASE '
|
|
. 'WHEN completed_at IS NULL THEN '
|
|
. 'priority '
|
|
. 'ELSE '
|
|
. '-1 '
|
|
. 'END ) DESC , missing_dependencies ASC NULLS FIRST , added_at DESC'
|
|
)->execute( $item->id );
|
|
}
|
|
|
|
|
|
public function addTask( $item , $title , $priority , $description )
|
|
{
|
|
$result = $this->query( 'SELECT add_task( $1 , $2 , $3 , $4 , $5 ) AS error' )
|
|
->execute( $item , $title , $description , $priority , $_SESSION[ 'uid' ] );
|
|
return $result[0]->error;
|
|
}
|
|
|
|
|
|
public function get( $id )
|
|
{
|
|
$result = $this->query(
|
|
'SELECT t.task_id AS id, t.task_title AS title, t.item_id AS item ,'
|
|
. 't.task_description AS description, t.task_added AS added_at, '
|
|
. 'u1.user_view_name AS added_by, ct.completed_task_time AS completed_at, '
|
|
. 'u2.user_view_name AS completed_by, t.user_id AS uid , '
|
|
. 't.task_priority AS priority '
|
|
. 'FROM tasks t '
|
|
. 'INNER JOIN users_view u1 ON u1.user_id = t.user_id '
|
|
. 'LEFT OUTER JOIN completed_tasks ct ON ct.task_id = t.task_id '
|
|
. 'LEFT OUTER JOIN users_view u2 ON u2.user_id = ct.user_id '
|
|
. 'WHERE t.task_id = $1' )->execute( $id );
|
|
if ( empty( $result ) ) {
|
|
return null;
|
|
}
|
|
|
|
$task = $result[ 0 ];
|
|
$task->notes = $this->query(
|
|
'SELECT n.note_id AS id , n.user_id AS uid , u.user_view_name AS author , '
|
|
. 'n.note_added AS added_at , n.note_text AS "text" '
|
|
. 'FROM notes n '
|
|
. 'INNER JOIN users_view u USING (user_id) '
|
|
. 'WHERE n.task_id = $1 '
|
|
. 'ORDER BY n.note_added DESC' )->execute( $id );
|
|
$task->dependencies = $this->query(
|
|
'SELECT t.task_id AS id , t.task_title AS title , t.item_id AS item , '
|
|
. 'i.item_name AS item_name , '
|
|
. '( ct.completed_task_time IS NOT NULL ) AS completed , '
|
|
. 'tl.total_missing_dependencies AS missing_dependencies '
|
|
. 'FROM task_dependencies td '
|
|
. 'INNER JOIN tasks t ON t.task_id = td.task_id_depends '
|
|
. 'INNER JOIN items i USING ( item_id ) '
|
|
. 'INNER JOIN tasks_list tl ON tl.id = t.task_id '
|
|
. 'LEFT OUTER JOIN completed_tasks ct ON ct.task_id = t.task_id '
|
|
. 'WHERE td.task_id = $1 '
|
|
. 'ORDER BY i.item_name , t.task_priority DESC , t.task_title' )->execute( $id );
|
|
$task->reverseDependencies = $this->query(
|
|
'SELECT t.task_id AS id , t.task_title AS title , t.item_id AS item , '
|
|
. 'i.item_name AS item_name , '
|
|
. '( ct.completed_task_time IS NOT NULL ) AS completed '
|
|
. 'FROM task_dependencies td '
|
|
. 'INNER JOIN tasks t USING( task_id ) '
|
|
. 'INNER JOIN items i USING ( item_id ) '
|
|
. 'LEFT OUTER JOIN completed_tasks ct USING ( task_id ) '
|
|
. 'WHERE td.task_id_depends = $1 '
|
|
. 'ORDER BY i.item_name , t.task_priority DESC , t.task_title' )->execute( $id );
|
|
$task->possibleDependencies = $this->query(
|
|
'SELECT t.task_id AS id , t.task_title AS title , t.item_id AS item , '
|
|
. 'i.item_name AS item_name '
|
|
. 'FROM tasks_possible_dependencies( $1 ) t '
|
|
. 'INNER JOIN items i USING ( item_id ) '
|
|
. 'ORDER BY i.item_name , t.task_priority , t.task_title' )->execute( $id );
|
|
|
|
return $task;
|
|
}
|
|
|
|
|
|
public function canDelete( $task )
|
|
{
|
|
if ( $task->completed_by !== null ) {
|
|
$ts = strtotime( $task->completed_at );
|
|
return ( time() - $ts > 7 * 3600 * 24 );
|
|
}
|
|
$ts = strtotime( $task->added_at );
|
|
return ( time() - $ts < 600 ) && ( $task->uid == $_SESSION[ 'uid' ] );
|
|
}
|
|
|
|
|
|
public function canFinish( $task )
|
|
{
|
|
assert( $task->completed_at == null );
|
|
foreach ( $task->dependencies as $dependency ) {
|
|
if ( $dependency->completed != 't' ) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public function canRestart( $task )
|
|
{
|
|
assert( $task->completed_at != null );
|
|
foreach ( $task->reverseDependencies as $dependency ) {
|
|
if ( $dependency->completed == 't' ) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public function delete( $task )
|
|
{
|
|
$this->query( 'DELETE FROM tasks WHERE task_id = $1' )->execute( $task );
|
|
}
|
|
|
|
|
|
public function finish( $task , $noteText )
|
|
{
|
|
$this->query( 'SELECT finish_task( $1 , $2 , $3 )' )
|
|
->execute( $task , $_SESSION[ 'uid' ] , $noteText );
|
|
}
|
|
|
|
|
|
public function restart( $task , $noteText )
|
|
{
|
|
$this->query( 'SELECT restart_task( $1 , $2 , $3 )' )
|
|
->execute( $task , $_SESSION[ 'uid' ] , $noteText );
|
|
}
|
|
|
|
public function updateTask( $id , $item , $title , $priority , $description )
|
|
{
|
|
$result = $this->query( 'SELECT update_task( $1 , $2 , $3 , $4 , $5 ) AS error' )
|
|
->execute( $id , $item , $title , $description , $priority );
|
|
return $result[0]->error;
|
|
}
|
|
|
|
public function addNote( $task , $note )
|
|
{
|
|
$this->query( 'INSERT INTO notes ( task_id , user_id , note_text ) VALUES ( $1 , $2 , $3 )' )
|
|
->execute( $task , $_SESSION[ 'uid' ] , $note );
|
|
}
|
|
|
|
public function getNote( $id )
|
|
{
|
|
$query = $this->query(
|
|
'SELECT n.note_id AS id , n.note_text AS text , n.note_added AS added_at , '
|
|
. 'n.task_id AS task , '
|
|
. '( n.user_id = $2 AND t.task_id IS NULL ) AS editable '
|
|
. 'FROM notes n '
|
|
. 'LEFT OUTER JOIN completed_tasks t USING (task_id) '
|
|
. 'WHERE n.note_id = $1' );
|
|
$result = $query->execute( $id , $_SESSION[ 'uid' ] );
|
|
if ( empty( $result ) ) {
|
|
return null;
|
|
}
|
|
$result[ 0 ]->editable = ( $result[ 0 ]->editable == 't' );
|
|
return $result[ 0 ];
|
|
}
|
|
|
|
public function deleteNote( $id )
|
|
{
|
|
$this->query( 'DELETE FROM notes WHERE note_id = $1' )->execute( $id );
|
|
}
|
|
|
|
public function updateNote( $id , $text )
|
|
{
|
|
$this->query( 'UPDATE notes SET note_text = $2 , note_added = now( ) WHERE note_id = $1' )
|
|
->execute( $id , $text );
|
|
}
|
|
|
|
public function addDependency( $id , $dependency )
|
|
{
|
|
$result = $this->query( 'SELECT tasks_add_dependency( $1 , $2 ) AS error' )
|
|
->execute( $id , $dependency );
|
|
return $result[0]->error;
|
|
}
|
|
|
|
public function deleteDependency( $from , $to )
|
|
{
|
|
$this->query( 'DELETE FROM task_dependencies WHERE task_id = $1 AND task_id_depends = $2' )
|
|
->execute( $from , $to );
|
|
}
|
|
|
|
}
|