/** * 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; } } }
/** * 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; }
/** * Ticket statuses. */ public function statusesAction() { return $this->jsonResponse(Status::select()->execute()->fetchAll()); }
/*! * 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]);
/** * 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']]); } }
/** * 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]; }
/** * 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]); } }); }
/** * 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(); } }
function createStatus() { $status = new Status(['name' => 'status-' . mkRandomHash(5) . '-name']); $status->save(); return $status; }