Since: 3.0.0
Author: Jack P.
Inheritance: extends Avalon\Database\Model
Example #1
0
 /**
  * Update the `is_closed` property.
  */
 public function updateIsClosed()
 {
     $this->isClosing = false;
     $this->isReopening = false;
     // Don't do anything unless the status has changed
     if ($this->original_status != $this->status_id) {
         $status = Status::find($this->status_id);
         // Did the status change to open/started or closed?
         if ($status->status >= 1) {
             if ($this->is_closed) {
                 $this->isClosing = false;
                 $this->isReopening = true;
             }
             $this->is_closed = false;
             $this->isClosing = false;
         } elseif ($status->status == 0) {
             if (!$this->is_closed) {
                 $this->isClosing = true;
             }
             $this->is_closed = true;
         }
     }
 }
Example #2
0
 /**
  * Returns options for the specific ticket filter.
  *
  * @param string $filter
  *
  * @return array
  */
 public static function selectOptionsFor($filter, Project $project)
 {
     switch ($filter) {
         // Milestone options
         case 'milestone':
             $options = $project->milestoneSelectOptions('slug');
             break;
             // Version options
         // Version options
         case 'version':
             $options = $project->milestoneSelectOptions('slug');
             break;
             // Type options
         // Type options
         case 'type':
             $options = Type::selectOptions('name');
             break;
             // Status options
         // Status options
         case 'status':
             $options = Status::selectOptions('name');
             break;
             // Component options
         // Component options
         case 'component':
             $options = Component::selectOptions($project->id, 'name');
             break;
             // Priority options
         // Priority options
         case 'priority':
             $options = Priority::selectOptions('name');
             break;
             // Severity options
         // Severity options
         case 'severity':
             $options = Severity::selectOptions('name');
             break;
     }
     return $options;
 }
Example #3
0
 /**
  * Ticket statuses.
  */
 public function statusesAction()
 {
     return $this->jsonResponse(Status::select()->execute()->fetchAll());
 }
Example #4
0
/*!
 * Traq Lite
 * Copyright (c) 2009-2016 Jack P.
 * https://github.com/nirix/traq-lite
 *
 * Licensed under the BSD 3-Clause license.
 */
use Traq\Models\Status;
$query = db()->prepare('SELECT * FROM ' . PREFIX . 'statuses WHERE id = ? LIMIT 1');
$query->bindValue(1, Request::$properties['id']);
$query->execute();
$status = $query->fetch();
if (!$status) {
    return show404();
}
$status = new Status($status);
if (Request::$method == 'POST') {
    $status->set(['name' => Request::$post['name'], 'status' => Request::$post['status']]);
    if ($status->validate()) {
        db()->beginTransaction();
        $query = db()->prepare('UPDATE ' . PREFIX . 'statuses SET name = :name, status = :status WHERE id = :id LIMIT 1');
        $query->bindValue(':id', $status['id']);
        $query->bindValue(':name', $status['name']);
        $query->bindValue(':status', $status['status']);
        $query->execute();
        db()->commit();
        return redirect('/admin/statuses');
    }
}
return view('admin/statuses/edit.phtml', ['status' => $status]);
Example #5
0
 /**
  * Update ticket.
  *
  * @param integer $id id matching ticket_id
  */
 public function updateAction($id)
 {
     if (!$this->hasPermission('update_tickets') || !$this->hasPermission('comment_on_tickets')) {
         return $this->show403();
     }
     // Fetch the ticket, but filter it by ticket_id and project_id
     $ticket = ticketQuery()->addSelect('t.*')->where('t.ticket_id = ?')->andWhere('t.project_id = ?')->setParameter(0, $id)->setParameter(1, $this->currentProject['id'])->fetch();
     if ($this->hasPermission('update_tickets')) {
         $data = $this->ticketParamsUpdate();
         $changes = $this->makeChanges($ticket, $data);
     } else {
         $data = [];
         $changes = [];
     }
     if ($this->hasPermission('comment_on_tickets')) {
         $comment = empty(Request::$post->get('comment')) ? null : Request::$post->get('comment');
     }
     if (count($changes) || Request::$post->get('comment')) {
         $update = new TicketHistory(['user_id' => $this->currentUser['id'], 'ticket_id' => $ticket['id'], 'changes' => count($changes) ? $changes : null, 'comment' => isset($comment) ? $comment : null]);
         $ticket->set($data);
         if ($ticket->validate()) {
             $ticket->save();
             $update->save();
             // Which action is being performed?
             $status = Status::find($ticket->status_id)->name;
             if (!count($changes)) {
                 $action = 'ticket_comment';
                 $status = null;
             } elseif ($ticket->isClosing) {
                 $action = 'ticket_closed';
             } elseif ($ticket->isReopening) {
                 $action = 'ticket_reopened';
             } else {
                 $action = 'ticket_updated';
                 $status = null;
             }
             $timeline = Timeline::updateTicketEvent($this->currentUser, $ticket, $action, $status);
             $timeline->save();
             return $this->redirectTo('ticket', ['pslug' => $this->currentProject['slug'], $ticket['ticket_id']]);
         } else {
             $this->set('ticketModel', $ticket);
             return $this->render('tickets/update.phtml', ['ticket' => $ticket]);
         }
     } else {
         return $this->redirectTo('ticket', ['pslug' => $this->currentProject['slug'], $ticket['ticket_id']]);
     }
 }
Example #6
0
 /**
  * Returns an array containing the open, started and closed ticket count queries.
  *
  * @return array
  */
 protected function getTicketCountQueries()
 {
     // Open ticket count
     $openQuery = Ticket::select('COUNT(t.id)')->where('t.milestone_id = m.id')->andWhere('t.is_closed = :open_count_is_closed');
     // Started ticket count
     $startedQuery = Ticket::select('COUNT(t.id)')->where('t.milestone_id = m.id')->andWhere('s.status = 2')->leftJoin('t', Status::tableName(), 's', 's.id = t.status_id');
     // Closed query count
     $closedQuery = Ticket::select('COUNT(t.id)')->where('t.milestone_id = m.id')->andWhere('t.is_closed = :closed_count_is_closed');
     return [$openQuery, $startedQuery, $closedQuery];
 }
Example #7
0
 /**
  * Project changelog.
  */
 public function changelogAction()
 {
     $this->addCrumb($this->translate('changelog'), $this->generateUrl('changelog'));
     $types = [];
     $milestones = [];
     // Get milestones
     $milestonesQuery = $this->currentProject->milestones()->select('id', 'name', 'slug')->where('status = 2')->orderBy('display_order', 'DESC')->fetchAll();
     foreach ($milestonesQuery as $milestone) {
         $milestones[$milestone['id']] = ['name' => $milestone['name'], 'slug' => $milestone['slug'], 'tickets' => []];
     }
     // Get tickets
     if (count($milestones)) {
         $tickets = $this->currentProject->tickets()->select('t.ticket_id', 't.summary', 't.milestone_id', 'status.id AS status_id', 'status.name AS status_name', 'status.show_on_changelog AS status_show_on_changelog', 'type.id AS type_id', 'type.name AS type_name', 'type.bullet AS type_bullet', 'type.show_on_changelog AS type_show_on_changelog');
         // Left join the status and types values
         $tickets->leftJoin('t', Status::tableName(), 'status', 'status.id = t.status_id');
         $tickets->leftJoin('t', Type::tableName(), 'type', 'type.id = t.type_id');
         // Filter by closed and milestones
         $tickets->where('is_closed = :is_closed')->andWhere($tickets->expr()->in('milestone_id', array_keys($milestones)))->orderBy('type_bullet', 'ASC');
         $tickets->setParameter('is_closed', true, 'boolean');
         foreach ($tickets->fetchAll() as $ticket) {
             $ticketInfo = ['ticket_id' => $ticket['ticket_id'], 'summary' => $ticket['summary'], 'type_id' => $ticket['type_id'], 'type_name' => $ticket['type_name'], 'status_id' => $ticket['status_id'], 'status_name' => $ticket['status_name']];
             // Add types
             if (!isset($types[$ticket['type_id']])) {
                 $types[$ticket['type_id']] = ['id' => $ticket['type_id'], 'name' => $ticket['type_name'], 'bullet' => $ticket['type_bullet']];
             }
             if ($ticket['status_show_on_changelog'] && $ticket['type_show_on_changelog']) {
                 $milestones[$ticket['milestone_id']]['tickets'][] = $ticketInfo;
             }
         }
     }
     // And now we get an array without the milestone ID's as the index.
     $milestones = array_values($milestones);
     return $this->respondTo(function ($format) use($types, $milestones) {
         if ($format == 'html') {
             return $this->render('projects/changelog.phtml', ['types' => $types, 'milestones' => $milestones]);
         } elseif ($format == 'json') {
             return $this->jsonResponse($milestones);
         } elseif ($format == 'txt') {
             return $this->render('projects/changelog.txt.php', ['types' => $types, 'milestones' => $milestones]);
         }
     });
 }
Example #8
0
 /**
  * Insert statuses.
  */
 public function insertStatuses()
 {
     $statuses = [['name' => "New", 'status' => 1, 'show_on_changelog' => false], ['name' => "Accepted", 'status' => 1, 'show_on_changelog' => false], ['name' => "Started", 'status' => 2, 'show_on_changelog' => false], ['name' => "Closed", 'status' => 0, 'show_on_changelog' => true], ['name' => "Completed", 'status' => 0, 'show_on_changelog' => true]];
     foreach ($statuses as $status) {
         $model = new Status($status);
         $model->save();
     }
 }
Example #9
0
function createStatus()
{
    $status = new Status(['name' => 'status-' . mkRandomHash(5) . '-name']);
    $status->save();
    return $status;
}