public function __construct() { parent::__construct(); $this->title($this->translate('milestones')); $this->before(['edit', 'save', 'delete', 'destroy'], function () { $this->object = Milestone::find(Request::$properties->get('id')); if (!$this->object || $this->object->project_id != $this->currentProject['id']) { return $this->show404(); } }); $this->after('save', function () { if ($this->object->isBeingCompleted) { Timeline::milestoneCompletedEvent($this->currentUser, $this->object)->save(); } }); }
/** * Create page. */ public function createAction() { $page = new WikiPage($this->pageParams()); if ($page->save()) { $page->revision()->set(['user_id' => $this->currentUser->id, 'wiki_page_id' => $page->id]); $page->revision()->save(); $page->revision_id = $page->revision()->id; $page->save(); $page->revision()->save(); // Create timeline event Timeline::wikiPageCreatedEvent($this->currentUser, $page)->save(); return $this->redirectTo('wiki_page', ['slug' => $page['slug']]); } else { return $this->render('wiki/new.phtml', ['page' => $page]); } }
/** * Delete timeline event. * * @param integer $id */ public function deleteEventAction($id) { if (!$this->hasPermission('delete_timeline_events')) { return $this->show403(); } $event = TimelineModel::select()->where('id = ?')->andWhere('project_id = ?')->setParameter(0, $id)->setParameter(1, $this->currentProject['id'])->fetch(); if ($event) { $event->delete(); } return $this->respondTo(function ($format) use($event) { if ($format == 'html' || !$event) { return $this->redirectTo('timeline', ['pslug' => $this->currentProject['slug']]); } else { return $this->renderJs('timeline/delete_event.js.php', ['event' => $event]); } }); }
/** * 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']]); } }
<?php use Traq\Models\Timeline; $testSuite->createGroup('Requests / Projects / Timeline', function ($g) { $project = createProject(); $ticket = $project->tickets()->fetch() ?: createTicket($project); $wikiPage = createWikiPage($project); $g->test('Empty timeline', function ($t) use($project, $ticket, $wikiPage) { $resp = $t->visit('timeline', ['routeTokens' => ['pslug' => $project['slug']]]); $t->assertContains($project['name'], $resp->body); $t->assertContains('<h1 class="page-header">Timeline</h1>', $resp->body); $t->assertNotContains($ticket['summary'], $resp->body); }); $g->test('With events', function ($t) use($project, $ticket, $wikiPage) { $newTicketEvent = Timeline::newTicketEvent($ticket->user(), $ticket); $newTicketEvent->save(); $updatedTicketEvent = Timeline::updateTicketEvent($ticket->user(), $ticket, 'ticket_updated', $ticket->status()['name']); $updatedTicketEvent->save(); $closedTicketEvent = Timeline::updateTicketEvent($ticket->user(), $ticket, 'ticket_closed', $ticket->status()['name']); $closedTicketEvent->save(); $completedMilestoneEvent = Timeline::milestoneCompletedEvent($ticket->user(), $ticket->milestone()); $completedMilestoneEvent->save(); $wikiPageCreatedEvent = Timeline::wikiPageCreatedEvent($ticket->user(), $wikiPage); $wikiPageCreatedEvent->save(); $resp = $t->visit('timeline', ['routeTokens' => ['pslug' => $project['slug']]]); $t->assertContains($project['name'], $resp->body); $t->assertContains('<h1 class="page-header">Timeline</h1>', $resp->body); $t->assertContains($ticket['summary'], $resp->body); $t->assertContains($wikiPage['title'], $resp->body); }); });
public function createAction() { $this->addCrumb($this->translate('new_page'), $this->generateUrl('wiki_new')); $page = new WikiPage($this->pageParams()); $page->revision_id = 0; $revision = new WikiRevision($this->revisionParams()); $revision['revision'] = 1; // Validate page and revision $page->validate(); $revision->validate(); if (!$page->hasErrors() && !$revision->hasErrors()) { $page->save(); $revision->wiki_page_id = $page->id; $revision->save(); $page->revision_id = $revision->id; $page->save(); $timelineEvent = TimelineModel::wikiPageCreatedEvent($this->currentUser, $page); $timelineEvent->save(); return $this->redirectTo('wiki_page', ['slug' => $page['slug']]); } return $this->render('wiki/new.phtml', ['page' => $page, 'revision' => $revision]); }